RAG for Networking: The Intelligence Layer Powering Autonomous Networks
The Shift Toward Reasoning Networks Every evolution in networking has pursued one goal which is reducing human friction.From…
Read More
Many failed SONiC REST calls carry a perfectly valid payload. They fail because something they depend on isn’t there yet. Here is how SONiC tracks...

Many failed SONiC REST calls carry a perfectly valid payload. They fail because something they depend on isn’t there yet. Here is how SONiC tracks those dependencies, and how to get the order right.
SONiC REST API configuration requests can fail when they reference objects that have not yet been created. Even when a JSON payload is valid, the native SONiC YANG models and Config Validation Library (CVL) describe and validate dependencies between configuration objects.
To make configuration workflows more predictable:
Create foundational objects before dependent objects; use YANG leaf ref paths and must/when expressions to identify dependencies; and create objects in dependency order, deleting them in reverse order. Check which models are served by RESTCONF on the exact SONiC build you deploy, and take particular care with union-typed references.
For example, configure the VRF, BGP instance, peer group, and BGP neighbor in that order. The specific behavior can vary by SONiC distribution and release.
You have written the payload carefully. The JSON matches the YANG model, the field names are right, and the values are in range. You send a PATCH to create a BGP neighbor on a SONiC switch, and the switch answers:
{
"error-message": "No instance found for ‘PG_SPINE'"
}
Nothing is wrong with the request itself. It simply arrived too early: the peer group it refers to doesn’t exist yet.
SONiC configuration is a graph of tables that reference each other, and the REST API enforces that graph. Once you understand how the references are described and checked, these errors stop being surprises and become something you can plan for. In this post we look at how the native SONiC YANG models describe dependencies, how the management framework enforces them, and how to order requests so that your automation works the first time.
A Thin Layer over CONFIG_DB
SONiC keeps its configuration in a Redis database called CONFIG_DB. Each daemon on the switch, from bgpcfgd to orchagent, watches the tables it cares about and acts when they change. The native SONiC YANG models (the sonic-*.yang files in the sonic-yang-models package) describe those tables almost one to one:
module sonic-vrf one YANG module
container sonic-vrf the module root
container VRF one CONFIG_DB table
list VRF_LIST one entry per key
key "name" → VRF|Vrf_Blue
The REST path follows the model exactly, which makes the API predictable. Once you know the table, you know the URL:
curl -k -u <user>:<password> -X PATCH \
-H 'Content-Type: application/yang-data+json' \
https://<switch>/restconf/data/sonic-vrf:sonic-vrf/VRF \
-d '{"sonic-vrf:VRF":{"VRF_LIST":[{"name":"Vrf_Blue"}]}}'
That request writes the key VRF|Vrf_Blue into CONFIG_DB. Before it gets there, it passes through two gates in the management framework.

Figure 1. The path of a REST write
The first gate binds the JSON to the YANG schema. A wrong field name, or a string where the model expects a number, is caught here and typically returns HTTP 400. The second gate is CVL, the Config Validation Library. CVL checks the request against the rest of the database: does every referenced object exist, and is anything still pointing at the object being deleted? A failure here comes back as an application error with a cvl-error block that explains it. In current releases that is usually reported as HTTP 500.
TIP
A response with a cvl-error block is a permanent error, not a server fault, so retrying the same request won’t help. Read error-app-tag instead: instance-required means something is missing, and instance-in-use means something still depends on the object you’re deleting.
First Question: Is the Model Even on the API?
It is natural to assume that every model in sonic-yang-models can be configured over REST. In practice, the REST server only serves the models that were included when the management framework was built. Some models are packaged only so that other models can reference their types or tables, and some aren’t packaged at all. The exact set varies from one SONiC distribution and release to another.

Figure 2. Which models are on the API
This has a practical consequence: a model that is served can depend on one that isn’t. A route-map, for example, can reference prefix sets that live in a separate model. If that model isn’t exposed on your build, you need another configuration path for that part, such as the equivalent OpenConfig model.
Checking a model takes one request. A GET on the module root returns 200 if the model is served, and 404 if it isn’t:
curl -sk -o /dev/null -w '%{http_code}\n' -u <user>:<password> \
https://<switch>/restconf/data/sonic-vrf:sonic-vrf
Run that check against every model your automation depends on, on the exact build you plan to deploy.
How SONiC Describes What Depends on What
Dependencies between tables are written into the YANG models in three ways.
The most common is the `leafref`: a field whose value must match an existing entry in another table. A BGP peer group’s vrf_name must match a BGP instance, and a port’s QoS map binding must name a map that exists.
Some references are written as `must` or `when` expressions instead. These can check membership, conditions or the existence of entries in other tables, and CVL enforces them just as it enforces leafrefs.
The third way looks like a dependency but often isn’t: the `import` statement. A module imports another to use its names, very often just to reuse a type definition. A module that imports sonic-vrf does not necessarily reference a VRF entry. If you build a dependency list from imports, you will over-constrain your ordering and miss references that live in must expressions. Read the leafref paths and must/when expressions instead.
The union subtlety
Many fields accept either a fixed keyword or a reference. The VRF name of a BGP instance is a good example: it can be the literal default, or the name of an entry in the VRF table.
leaf vrf_name {
type union {
type string {
pattern 'default';
}
type leafref {
path "/vrf:sonic-vrf/vrf:VRF/vrf:VRF_LIST/vrf:name";
}
}
}
Union-typed references are harder for a validator to handle than plain ones, because a value that doesn’t match the reference might still be a valid keyword. Depending on the release, the reference branch of a union may be enforced strictly, or only when the target is deleted.

Figure 3. Plain vs union references
The safe assumption is simple: don’t rely on the switch to catch an out-of-order request when the field is a union. Union-typed references are common in exactly the fields automation touches most often: VRF names, and interface names that may be a port, a port-channel or a VLAN. If such a request is accepted before its target exists, the downstream daemons are left to deal with a dangling reference. Make your own ordering enforce these dependencies, and verify how your build behaves.
Five Practical Lessons
1. Plain references are enforced in both directions. You can’t create an object that points to a missing entry, and you can’t delete an entry that something still references. Creating a QoS binding to a map that doesn’t exist fails with CVL’s Dependent Data is missing. Deleting that map while a port still uses it fails with instance is in use.
2. The model’s names are not the database’s names. Key and field names come from the YANG model, and they don’t always match what you see in CONFIG_DB or in the CLI. In sonic-vrf, for example, the list key is name, even though other tables refer to the VRF through a field called vrf_name. A mismatch is rejected at the schema gate with a message like JSON contains unexpected field.
3. Numbers must be numbers. CONFIG_DB stores every value as a string, but the YANG model has real types. In a DSCP-to-traffic-class map, the traffic class is an integer, so “tc”: “3” is rejected and “tc”: 3 is accepted. A neighbouring field in a related model may well be a string. Check the YANG type of every leaf rather than copying values from the database.
4. Inside one module, let the server order the tables. When a single module holds both a parent table and a dependent table, such as VLAN and VLAN_MEMBER in sonic-vlan, you can send both in one PATCH on the module root. The management framework sorts the tables by dependency before writing them. When the parent lives in a different module, for example a VRF for a BGP instance, send separate requests in the right order.
5. A failed delete stops the chain. If one delete in a teardown fails, every object above it stays referenced, so every later delete fails too. A cleanup script that stops at the first error leaves the switch half configured, and one that keeps going produces a wall of “in use” errors. Either way, check what is left at the end, and design teardown as carefully as setup.
Build in Layers, Tear Down in Reverse
If you follow the references between models, a natural create order emerges. Each module depends only on modules in the layers below it. The exact layering depends on which models your build serves, but for the most common features it looks like this.

Figure 4. Build in layers, tear down in reverse
Foundational objects come first: VRFs, ports, loopbacks, schedulers, WRED profiles, QoS maps and buffer pools. Interfaces and port-channels build on those, VLANs, ACLs and route-maps come next, and routing protocols sit on top, with BGP neighbors last. Create from the bottom up, delete from the top down, and CVL will have no reason to refuse you.
You can derive this layering for your own build. List the models your automation uses, collect each one’s leafref paths and must/when expressions, and sort the models so that every reference points downward. The result is a reusable ordering table for your scripts.
Walkthrough: BGP in a VRF
Here is the order in practice for a BGP instance in a VRF, with one peer group and one neighbor. It involves four modules, one request each. The addresses and AS numbers below come from the documentation ranges.

Figure 5. BGP in a VRF: four requests, one order
R="curl -sk -u <user>:<password> -H Content-Type:application/yang-data+json"
B=https://<switch>/restconf/data
# 1. The VRF
$R -X PATCH $B/sonic-vrf:sonic-vrf/VRF \
-d '{"sonic-vrf:VRF":{"VRF_LIST":[{"name":"Vrf_Blue"}]}}'
# 2. A BGP instance in that VRF
$R -X PATCH $B/sonic-bgp-global:sonic-bgp-global/BGP_GLOBALS \
-d '{"sonic-bgp-global:BGP_GLOBALS":{"BGP_GLOBALS_LIST":[
{"vrf_name":"Vrf_Blue","local_asn":64500,"router_id":"192.0.2.1"}]}}'
# 3. A peer group
$R -X PATCH $B/sonic-bgp-peergroup:sonic-bgp-peergroup/BGP_PEER_GROUP \
-d '{"sonic-bgp-peergroup:BGP_PEER_GROUP":{"BGP_PEER_GROUP_LIST":[
{"vrf_name":"Vrf_Blue","peer_group_name":"PG_SPINE","asn":64501}]}}'
# 4. A neighbor in that peer group
$R -X PATCH $B/sonic-bgp-neighbor:sonic-bgp-neighbor/BGP_NEIGHBOR \
-d '{"sonic-bgp-neighbor:BGP_NEIGHBOR":{"BGP_NEIGHBOR_LIST":[
{"vrf_name":"Vrf_Blue","neighbor":"198.51.100.2","peer_group_name":"PG_SPINE"}]}
}'
Sent in this order, each request succeeds. Send step 4 before step 3, and the neighbor is rejected because its peer group is missing. Send step 3 for a VRF that has no BGP instance, and the peer group is rejected. Step 2 is the one to watch: its vrf_name is a union, so depending on your build, sending it before step 1 may not be caught at all.
If the BGP instance or peer group uses route-maps, those and anything they match (prefix sets, community sets) belong to lower layers and must exist before step 2.
The same pattern applies to QoS. To classify traffic on a port, create the DSCP-to-traffic-class map, the traffic-class-to-queue map and a scheduler first. Then bind the maps to the port in PORT_QOS_MAP, and attach the scheduler to a queue in QUEUE. Map references in PORT_QOS_MAP are plain leafrefs, so the switch enforces this chain fully.
Two Views of the Same Database
The native SONiC models are not the only way into CONFIG_DB. The management framework also serves OpenConfig models, which translate to the same tables. That gives you a useful fallback. If a native model on your build can’t perform an operation cleanly, or a dependency lives in a model that isn’t exposed, the OpenConfig view often can.
Native models are the most direct choice when you want precise control over CONFIG_DB. OpenConfig models are the better choice when you want vendor-neutral automation. Many teams use both, choosing per feature, and it’s worth knowing that both write to the same source of truth.
Key Takeaways
Reliable SONiC automation is not just about sending a valid configuration. It is about understanding the relationships between the objects being configured. By deriving the order from the YANG references and validating behavior on the target build, engineers can make configuration workflows more predictable and easier to troubleshoot.
Frequently Asked Questions
Why can a SONiC REST API request fail when the JSON payload is valid?
A request can reference a configuration object that does not exist yet. The YANG model may describe that dependency, and CVL can reject the change when the referenced object is missing.
What is CVL in SONiC?
CVL, the Config Validation Library, validates configuration changes against SONiC YANG models and checks dependencies between configuration objects in the database.
What is the recommended order for configuring BGP in a SONiC VRF?
The walkthrough in this article creates the VRF first, then the BGP instance, then the peer group, and finally the BGP neighbor. Dependencies such as route-maps and the sets they match must be created in lower layers first.
How can I identify dependencies in SONiC YANG models?
Inspect leafref paths and must/when expressions. An import statement alone does not necessarily mean that a configuration entry depends on an entry in the imported module, because imports may only reuse type definitions.
Are all SONiC YANG models available through RESTCONF?
No. The article explains that the REST server serves models included in the management framework build, and the available set can vary by SONiC distribution and release. Check the module root on the exact build you plan to deploy.
Should configuration objects be deleted in the same order they are created?
No. Create objects from foundational layers upward and delete them in reverse dependency order. Objects that are still referenced may not be deleted successfully.
Suggested primary keyword: SONiC REST API. Suggested secondary terms: SONiC RESTCONF configuration, SONiC network automation, SONiC YANG models, SONiC CVL validation, SONiC CONFIG_DB, and SONiC BGP configuration.
Further Reading
Behaviour can differ between SONiC distributions and releases. Verify the details described here on the build you deploy.
Next steps
Talk to an Infrastructure Expert to discuss how PalC can help you build production-grade, open networking solutions.