An automation repository cannot compile a vendor's YANG module because an imported module is missing; how do you resolve its dependency graph?
answer
- walk import and include
- [email protected] file naming
- pinned revision must exist
- unpinned means undefined
- no cycles, so topological order
basics
~20 sWalk the YANG module's import and include statements recursively, collecting every module and submodule. A revision-date demands that exact revision; an unpinned import may resolve to any revision, so supply one that defines everything referenced, before compiling.
solid answer
~50 sStart from the vendor module's header and collect the closure: every `import` names a module, every `include` a submodule, and each of those files has its own imports. RFC 7950's file-naming convention, `[email protected]`, is how a parser finds them. Where an `import` has a `revision-date`, that exact revision must be present — it is an error if it does not exist, and a newer file does not substitute because it keeps only the history, not the old definitions. Where it has none, RFC 7950 says it is undefined which revision is used, so supply one that defines everything the module references: a type such as `yang:date` exists only from the 2025-12-22 revision of `ietf-yang-types` (RFC 9911). Imports cannot be circular, so the set compiles in dependency order. Also check version rules: a 1.1 module cannot include a version 1 submodule.
code
yang · 16 linesmodule example-vendor-system {
yang-version 1.1;
namespace "https://example.com/ns/example-vendor-system";
prefix exv-sys;
import ietf-yang-types {
prefix yang;
revision-date 2013-07-15; // needs [email protected]
}
import ietf-inet-types {
prefix inet; // unpinned: revision undefined
}
include example-vendor-system-ntp; // submodule file must be present
revision 2026-02-10 { description "Vendor release."; }
}go deeper
Know that a YANG module cannot compile until every module it imports and every submodule it includes is present.
Explain the file-naming convention and the difference between a pinned import (that exact revision) and an unpinned one (revision undefined).
Diagnose the real failures: a pinned revision missing, an unpinned import resolved to an old file lacking a typedef, a missing submodule, or a version 1 and 1.1 mismatch.
Decide how the estate manages model sets: a committed, reviewed closure per device release, a pinning policy, and an owner for vendor model updates.
## The failure A vendor publishes a YANG model for its devices, and the automation repository's compile step stops with "module not found" or "unknown type". Resolving a module's dependency graph is the first thing any YANG tooling does, and it most often fails for reasons the language itself defines. (Fetching the files from a running device is another subject — the NETCONF model-discovery mechanisms; here the question is what the set must contain.) ## Step 1: build the closure Every YANG file names its dependencies in its header: 1. **`import <module>`** — a separate module whose typedefs, groupings, identities, features, extensions or schema nodes this file references. It must be present for the file to compile. 2. **`include <submodule>`** — a submodule of this module. RFC 7950 says a module MUST include all its submodules, so a missing submodule is as fatal as a missing import. 3. **Each dependency's own header** — imported modules import others, and submodules carry their own imports. Collect this recursively until nothing new appears. Because RFC 7950 forbids circular chains of imports, the import graph is acyclic, so a dependency order (leaves first) always exists to compile in. ## Step 2: find the files RFC 7950 §5.2 says a module or submodule file SHOULD be named `module-or-submodule-name['@' revision-date].yang` (or `.yin`), where the date is the module's latest revision, and notes that parsers find imports and includes through this convention. A file named only `ietf-yang-types.yang` tells a tool nothing about its version, so keep the dated form in the repository. ## Step 3: honour revision-date — or know what you lose without it | Import form | What RFC 7950 says | What the repository must hold | |---|---|---| | `import m { prefix p; revision-date 2013-07-15; }` | Referenced typedefs, groupings, features, identities and extensions come from that revision; it is an error if it does not exist | The file whose newest revision is `2013-07-15` | | `import m { prefix p; }` | It is undefined which revision is used | Any revision that defines everything referenced — in practice the newest you trust | Two concrete failures with `ietf-yang-types`, whose RFC 9911 text records the revisions `2025-12-22`, `2013-07-15` (RFC 6991) and `2010-09-24` (RFC 6021): - **Pinned, but the file is missing.** The vendor module pins `2013-07-15` and the repository holds only `[email protected]`. The newer file lists 2013-07-15 in its history, but history is a list of dates and descriptions, not definitions, so the pinned revision does not exist and compilation fails. Add the 2013-07-15 file alongside. - **Unpinned, but resolved to an old file.** Another module imports `ietf-yang-types` without a date and uses `yang:date`. That typedef was added in the 2025-12-22 revision, so a repository holding only the 2013 file produces "unknown type". Supply the newer revision. Both files can sit in the same repository: YANG 1.1 allows different revisions of one module to be imported, and the dated names keep them apart. ## Step 4: check the version rules RFC 7950 §12 adds compatibility constraints the closure must satisfy: - a YANG 1.1 module MUST NOT include a YANG version 1 submodule, and the reverse is forbidden too; - a YANG version 1 module MUST NOT import a 1.1 module **by revision**, while a 1.1 module MAY import a version 1 module by revision. The `ietf-yang-types` text in RFC 9911 carries no `yang-version` statement, which makes it a version 1 module — so 1.1 vendor modules may import it by revision. ## Step 5: keep the set reproducible - **Commit the closure**, with dated file names, as a reviewed set rather than resolving on each run. - **Record what the vendor pinned and what floats**: the unpinned imports are where a later update silently changes types. - **Remember the conditional parts.** Nodes under a feature, and deviation modules shipped beside the model, change what a device actually implements; those belong to feature and deviation handling, but their files still have to resolve. ## Common mistakes - Assuming a newer file satisfies an older `revision-date`. - Ignoring submodules because "the module file is there". - Treating an unpinned import as "the latest" — RFC 7950 leaves the choice undefined, so the tool's search order decides.
- Why doesn't a newer ietf-yang-types file satisfy an import pinned to 2013-07-15?A revision statement in the newer file only records that the 2013 version existed, with its description; the 2013 definitions themselves are not in it. RFC 7950 makes it an error if the specified revision does not exist, and RFC 6020 stated it outright: revision-date must match the imported module's most recent revision statement.
- When should a module author pin imports with revision-date?RFC 9907 says the revision date SHOULD be present when groupings are used from the imported module, because a grouping copies nodes into the importer and a later revision could change them. Pinning buys stability at the cost of a republish to adopt new definitions; floating keeps up with additions that §11's rules keep backward compatible.
saying these in an interview costs you the question
- A newer revision of a module always satisfies an import pinned to an older revision-date.
- An import without revision-date is guaranteed to use the latest published revision.
- Submodules can be skipped if the main module file compiles on its own.
- Circular imports just need a second pass to resolve.
- A YANG version 1 module may import any 1.1 module by revision.