Safeguard
Security Guides•

Does an empty or missing dependsOn in CycloneDX mean no dependencies?

An empty dependsOn means the component has none. A component missing from the graph may have unknown dependencies. How to read the graph and mark gaps.

Safeguard Security Team
4 min read

In CycloneDX, a component declared with an empty dependsOn list has no dependencies. A component that does not appear in the dependency graph at all may have unknown dependencies, and the spec says not to read its absence as dependency-free. For unknown graphs, use compositions to say so.

What the schema says

The CycloneDX 1.6 JSON reference describes the dependencies array as defining the direct dependencies of a component or service. It states that components or services without their own dependencies must be declared as empty elements within the graph, and that those not represented in the graph may have unknown dependencies. It recommends that implementations assume the graph to be opaque and not an indicator of an object being dependency-free, and recommends using compositions to indicate unknown dependency graphs.

Each entry has a ref, pointing at a component's bom-ref, and a dependsOn list of other bom-refs.

"dependencies": [
  { "ref": "app", "dependsOn": ["lib-a", "lib-b"] },
  { "ref": "lib-a", "dependsOn": [] },
  { "ref": "lib-b", "dependsOn": ["lib-c"] }
]

Here lib-a is stated to have none. lib-c has no entry, so nothing is claimed about it.

Three states, three meanings

State in the fileWhat it means
Entry with dependsOn listing refsDirect dependencies are known
Entry with an empty dependsOnExplicitly none
No entry at allUnknown, per the spec's guidance

A generator that omits entries for leaf packages is not wrong by the loose reading, but it forces every reader to guess, so empty entries are better.

Why it matters for incident work

When a new vulnerability lands in lib-c, you want to know every path to it. If your SBOM tool assumes missing entries mean no dependencies, it may under-report. If it assumes missing means unknown, it should show a warning. Test your own tool with a file like the one above and see which behavior you get.

Flagging the gaps

The spec points to compositions for stating how complete parts of the BOM are. An aggregate value such as unknown dependencies, or incomplete, tells the reader which part of the graph to treat with caution. Use it when your generator could not resolve a part of the tree, for example when it read only a manifest and not a lockfile.

A short checklist

Does every component appear as a ref at least once? Do leaf components have explicit empty lists? Are there compositions entries for any area you could not resolve? Does your validation step fail when a dependsOn names a bom-ref that does not exist? Four yes answers means a graph you can rely on during a response.

Safeguard can generate SBOMs and run dependency scanning across your repositories, so the fields discussed here are checked on real projects instead of by hand. You can try the free scan at gold.safeguard.sh/scan.

Try it yourself

Open the demo, click through the component list, and look at how each package is identified and what is missing.

Click through it at your own pace, or open it full screen.

Quick check

What does an empty dependsOn mean?

In CycloneDX it states the component has no dependencies. The spec says components without dependencies must be declared as empty elements.

How do I say the graph is incomplete?

Use compositions, which the spec recommends for indicating unknown dependency graphs.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.