canton-network-docs
Development Issues
Development Issues - Canton Network Docs
Skip to main content
Fix: Use
Another common variant is confusing
Use
Fix:
SCU requires that new package versions remain wire-compatible with previous versions. You can add optional fields (with defaults), but you cannot remove or change existing fields.
Checklist:
Wait for the sandbox health endpoint to respond before sending requests:
Fix: Ensure the party submitting the command is listed as a
This is expected behavior in Canton’s UTXO-based model. The fix depends on your use case:
Upload your DAR file before submitting transactions:
Verify the package is known:
or in your logs as:
This error is usually caused by having an expression in the DAR whose serialized representation exceeds a depth of 1000 layers. This can be caused by long Daml scripts, since every use of a function call or
This script has 300 binds, well exceeding the tentative limit of 250 binds. We can refactor this script to instead define and use a helper
In general, it is a good idea to keep your scripts small, by maximizing code reuse and splitting logic into maintainable chunks.
In this case, the
You can see that the implicit, autogenerated definition of
The generated code for
This page addresses problems you are likely to hit while writing Daml code, connecting to APIs, and submitting transactions during local development.Documentation Index
Fetch the complete documentation index at: https://docs.canton.network/llms.txt
Use this file to discover all available pages before exploring further.
Daml Compilation Errors
Common type mismatches
The Daml compiler enforces strict typing. A frequent mistake is passing aContractId where the template type is expected, or vice versa.
fetch to retrieve the contract payload from a ContractId:
Party with Text:
getParty in Daml Script or pass the Party value directly rather than a string.
Missing imports
If the compiler reports an unknown type or function, you likely need an import. Daml does not auto-import modules.SCU compatibility check failures
When upgrading Daml packages, the Smart Contract Upgrade (SCU) compatibility checker may reject changes. Common violations include removing a field from a template or changing a field’s type.API Connection Problems
Wrong port
Each Canton component listens on a different port. If your application getsConnection refused, verify you are targeting the correct one:
- Ledger API (gRPC) — 5001
- JSON API — 7575
- Admin API — 5002
- Participant health — 5003
Auth token issues
If the Ledger API returnsUNAUTHENTICATED, your token may be expired, have the wrong audience, or lack the required scope.
- Token has the
daml_ledger_apiscope - Token audience matches
LEDGER_API_AUTH_AUDIENCEin your config - Token has not expired (check
expclaim)
Sandbox not ready yet
After runningdpm sandbox, the sandbox takes a few seconds to initialize. If your application connects immediately, it may fail with:
Transaction Failures in Development
Authorization errors
The most common transaction rejection is an authorization failure. Canton rejects transactions when the submitting party is not authorized as a signatory or controller.signatory or controller for the relevant choice. If a different party must act, use a delegation pattern where the authorized party creates a contract granting exercise rights.
Contention on the same contract
When two transactions try to exercise a consuming choice on the same contract simultaneously, one will be rejected:- Retry with backoff if the operation is idempotent
- Redesign the workflow to reduce single-contract bottlenecks (e.g., split a counter contract into shards)
- Sequence operations on the client side when ordering matters
Package vetting: DAR not uploaded
If your transaction references a package the validator does not know about, you get:For cn-quickstart, run
make setup then make build before make start. The build step compiles Daml and uploads DARs to the local environment.Additional Daml Error Messages
Error: “<X> is not authorized to commit an update”
This error occurs when there are multiple obligables on a contract. A cornerstone of Daml is that you cannot create a contract that will force some other party (or parties) into an obligation. This error means that a party is trying to do something that would force another parties into an agreement without their consent. To solve this, make sure each party is entering into the contract freely by exercising a choice. A good way of ensuring this is the “initial and accept” pattern: see the Daml patterns for more details.Error: “Argument is not of serializable type”
This error occurs when you’re using a function as a parameter to a template. For example, here is a contract that creates aPayout controller by a receiver’s supervisor:
Hovering over the compilation error displays:
Error: “Recursion limit overflow in module”
The error usually occurs when uploading a DAR to a ledger or using a script via the sandbox. It can manifest on upload as:<- to bind a variable in a do block can incur several layers of recursion in the do block’s serialized representation. Large datatypes with more than 160 fields with deriving clauses can also cause this.
Solving script recursion limits
Normally, one call insidedo introduces 4 layers of recursion, meaning about 250 binds in a script can cause an overflow. However, other expressions in a do block, such as let binds, also introduce a layer of recursion, so functions with fewer binds can also trigger the limit.
Possible workarounds include splitting a large script into multiple scripts or separating logic in the script out into helper functions. For example, assume you have written the following long script:
updateStateOnce, which runs all three choices together.
Note: In many cases, the compiler optimizes your script to produce an expression that does not break the recursion limit despite having many binds. In this example, we have given an intentionally convoluted example that is difficult for the compiler to optimize away.
By using this helper, each block of three exercises is reduced to a single bind, such that myScript now has only 100 binds, well below the recursion limit.
Solving datatype recursion limits
Large datatypes withderiving clauses can also cause overflow errors. Consider the following case of a datatype with 300 fields and a deriving Show instance:
deriving Show clause means that instance of Show MyData is automatically derived to be something like the following:
show has an expression that becomes more and more deeply nested as you go along. Once the number of fields exceeds about 160, this expression has the potential to reach the depth necessary to cause an overflow in its serialized representation in the DAR.
Similarly to Daml Scripts, the recommended workaround for this issue is to split your datatype into many parts. For example, we could create an additional datatype Helper which contains the elements a, b, and c, and use that within MyData:
MyData now has only 100 fields to traverse and nest. Similarly to scripts, it is a good idea to keep your datatypes small, by maximizing code reuse and splitting logic into maintainable chunks.