Two YANG modules in one toolchain import different revisions of the same module; when is that legal, and what goes wrong?
answer
- types follow the pinned revision
- nodes follow the implemented revision
- one implemented revision per server
- YANG 1.0 forbade multiple imports
basics
~20 sIt is legal: each YANG importer takes typedefs, groupings and identities from the revision it pins. But a server implements only one revision, so schema nodes come from that one, and same-named types can differ in value space.
solid answer
~50 sYANG 1.1 (RFC 7950) lets a module import a pinned revision of another, and even several revisions under different prefixes; RFC 6020 for version 1 forbade one module from importing multiple revisions of another. Each importer's `revision-date` fixes the typedefs, groupings, features, identities and extensions it receives, so two importers can see different value spaces for the same typedef name. Schema nodes are different: a server MUST NOT implement more than one revision of a module, and if an importer uses a node of it in `augment` or `path`, the server must implement a revision that has that node, whether or not the import was pinned. So types follow each importer's pin, while data nodes follow the single implemented revision. Typedef-only modules such as `ietf-yang-types` cause little trouble; skew hurts when importers rely on nodes or on value spaces that changed between revisions.
go deeper
Recall that an importer can pin a revision of a module, and that different modules may pin different revisions of the same one.
Explain which definitions follow the importer's pin (typedefs, groupings, identities) and which follow the server's single implemented revision (schema nodes).
Diagnose skew: same-named types with different value spaces, augment targets missing from the implemented revision, and groupings that drift under floating imports.
Set a pinning policy for shared modules across an estate, weighing reproducible builds against the cost of republishing every importer to adopt a fix.
## Two kinds of dependency When module A imports module B, A can use two different kinds of thing from B, and they resolve differently: | What A uses from B | Where it comes from | Can two importers see different versions? | |---|---|---| | Typedefs, groupings, features, identities, extensions | The revision A pins with `revision-date`; undefined if unpinned | **Yes** — each importer gets its own pinned revision | | Schema nodes, as `augment` or `path` targets or in `must` and `when` | The one revision of B the server implements | **No** — a server implements a single revision | Keeping these two columns apart is the whole answer. ## What the language allows - **YANG version 1 (RFC 6020)** said multiple revisions of the same module MUST NOT be imported by one module, and that an import's `revision-date` must match the most recent `revision` statement of the imported module. RFC 7950 does not obsolete RFC 6020; version 1 modules are still defined by it. - **YANG 1.1 (RFC 7950)** lists "allow imports of multiple revisions of a module" among its changes: one module may import several revisions provided it uses different prefixes, and different modules may of course pin different revisions. - **RFC 8525's YANG library** reflects this: it lists modules used only for import, keyed by name and revision, and states that multiple revisions can be used for import if import-by-revision is used — while a module is implemented in only one revision across all datastores. ## The worked example in RFC 7950 RFC 7950 §5.6.5 gives a compact case. Module `b` exists in two revisions: 1. `2015-01-01` defines a typedef `myenum` with one enum, `zero`, and an empty container `x`. 2. `2015-04-04` adds the enum `one` and a container `y` inside `x` — both changes allowed by the update rules. Module `a` imports `b` **by revision** `2015-01-01`, augments `/b:x` with a leaf `y` of type `b:myenum` under a feature `foo`, and imports a typedef-only module `c` without a date. Then: - A server implementing `a` with `foo` may implement `b` at either revision. Because `a` pinned 2015-01-01, the leaf `/b:x/a:y` has the **same type in both cases** — its value space is just `zero`, even if the server implements 2015-04-04 where `myenum` also has `one`. - A server that does not support `foo` need not implement `b` at all. - `c` is used only for a typedef, so the server lists it in the YANG library with conformance type `import`, and RFC 7950 says modules importing it without a date use the most recent revision listed. ## What goes wrong in practice 1. **Same type name, different value space.** One module pins an old revision of a shared typedef module and another floats to the newest. Two leaves typed with the "same" typedef now accept different values — an enum added later is valid in one and rejected in the other. Tooling that assumes one definition per name generates wrong validators. 2. **A node missing from the implemented revision.** A module was written against a newer revision whose container it augments, but the server implements an older one. The server cannot implement the importer correctly; RFC 7950 requires the implemented revision to define every node used in `augment` or `path`. 3. **Grouping drift.** A grouping copies nodes into the importer. Unpinned, a new revision of the imported module can add nodes to the importer's own tree — which is why RFC 9907 says the `revision-date` SHOULD be present when groupings are used. 4. **Version 1 neighbours.** A version 1 module cannot import a 1.1 module by revision at all, so a toolchain mixing both may be forced to leave some imports floating. ## How to manage it - **Inventory the pins.** For each shared module, list which importers pin which revision and which float. - **Float where risk is lowest** — typedef-only modules, whose updates §11 limits to compatible additions — and pin where groupings or exact value spaces matter. - **Align the implemented revision** with what augmenting modules need; which revision a device implements, and how it reports that, is part of conformance and model discovery. - **Upgrade deliberately.** Moving an importer to a newer pin is a republish of that importer, as RFC 7950 §5.1.1 describes: the author explicitly accepts the imported module's changes.
- Why does a typedef-only module such as ietf-yang-types tolerate revision skew better than a module with data nodes?It contributes no schema nodes, so a server need not implement it and can list it as import-only, in more than one revision; each importer simply compiles against its pinned revision. Skew still changes value spaces, but nothing in the data tree has to be reconciled.
- A module imports the same module twice, by two revision-dates, under the prefixes `old` and `new`; is that valid YANG 1.1?Yes. RFC 7950 §7.1.5 allows multiple revisions of one module to be imported provided different prefixes are used, so `old:t` and `new:t` refer to the typedef as each revision defines it. The same file is invalid YANG version 1, where RFC 6020 forbids importing multiple revisions.
saying these in an interview costs you the question
- A server can implement as many revisions of a module as its importers ask for.
- Pinning a revision-date also pins which revision of the module's data nodes the server implements.
- Two leaves using the same typedef name always accept the same values.
- YANG version 1 already let one module import several revisions of another.
- Floating imports are always safe because new revisions can only add things.