Describe the bug
The published v2.17.0 source release tarball of aws-greengrass-nucleus contains stale version metadata in two files:
pom.xml line 7: <version>2.16.0-SNAPSHOT</version>
conf/recipe.yaml line 12: ComponentVersion: '2.16.0'
This is not a one-off slip — it is systematic across at least four consecutive releases. The version metadata in every release tarball from v2.15.1 through v2.17.0 lags one or two versions behind the actual release tag:
| Release tag |
pom.xml <version> |
conf/recipe.yaml ComponentVersion |
| v2.15.1 |
2.15.0-SNAPSHOT |
'2.15.0' |
| v2.16.0 |
2.16.0-SNAPSHOT |
'2.15.0' |
| v2.16.1 |
2.16.0-SNAPSHOT |
'2.16.0' |
| v2.17.0 |
2.16.0-SNAPSHOT |
'2.16.0' |
Note the -SNAPSHOT suffix in every pom.xml — this is a development-build marker in Maven semantics, never expected to appear in a tagged release.
As a result, devices that build the Nucleus from source release tarballs (Yocto, custom OS images, container builds, anyone consuming the release zip rather than the installer scripts) end up running a Nucleus that internally self-reports a version which does not match the release they downloaded.
Steps to reproduce
- Download multiple release tarballs:
for v in 2.15.1 2.16.0 2.16.1 2.17.0; do
wget -q "https://github.com/aws-greengrass/aws-greengrass-nucleus/archive/refs/tags/v${v}.zip" \
-O "nucleus-v${v}.zip"
unzip -q "nucleus-v${v}.zip"
done
- Inspect version metadata across releases:
for v in 2.15.1 2.16.0 2.16.1 2.17.0; do
D="aws-greengrass-nucleus-${v}"
POM=$(grep "<version>" "${D}/pom.xml" | head -1 | tr -d ' ')
REC=$(grep "ComponentVersion" "${D}/conf/recipe.yaml")
echo "v${v}: ${POM} | ${REC}"
done
- Observe output:
v2.15.1: <version>2.15.0-SNAPSHOT</version> | ComponentVersion: '2.15.0'
v2.16.0: <version>2.16.0-SNAPSHOT</version> | ComponentVersion: '2.15.0'
v2.16.1: <version>2.16.0-SNAPSHOT</version> | ComponentVersion: '2.16.0'
v2.17.0: <version>2.16.0-SNAPSHOT</version> | ComponentVersion: '2.16.0'
- Confirm that each release does contain real new code (i.e. these are legitimate releases, not re-tags):
diff -rq aws-greengrass-nucleus-2.16.1/src/main aws-greengrass-nucleus-2.17.0/src/main | wc -l
# ~11 files differ — v2.17.0 adds a new uninstall lifecycle, changes Kernel.java,
# Lifecycle.java, GreengrassService.java, DeploymentConfigMerger.java, etc.
The releases are not byte-identical; the bug is solely that version metadata is never bumped as part of the release process.
Expected behavior
The v2.17.0 release tarball should have version metadata matching the release tag:
pom.xml should have <version>2.17.0</version> (no -SNAPSHOT)
conf/recipe.yaml should have ComponentVersion: '2.17.0'
Similarly for every previous release.
Actual behavior
When Nucleus is started from the v2.17.0 release tarball, it self-reports version=2.16.0. Specifically:
Kernel.java reads componentRecipe.getVersion() from conf/recipe.yaml → returns 2.16.0.
- The Nucleus then creates a
packages/nucleus/aws.greengrass.Nucleus/2.16.0/ directory alongside any 2.17.0/ directory present on disk and copies its own artifacts into it, based on the recipe version.
- FSS reports
coreVersion: 2.16.0 to AWS IoT Greengrass cloud.
setenv.GGC_VERSION is set to 2.16.0.
Reproducible Nucleus log line on a fresh install from the v2.17.0 zip:
Copy Nucleus artifacts ... destination=.../packages/nucleus/aws.greengrass.Nucleus/2.16.0/aws.greengrass.nucleus
... source=.../packages/nucleus/aws.greengrass.Nucleus/2.17.0/aws.greengrass.nucleus
I confirmed this is local to the device (not a cloud-side downgrade) by reproducing the directory split with the device disconnected from the internet — the 2.16.0/ directory is created locally by the Nucleus on startup based on recipe.yaml content.
Environment
- Greengrass nucleus version: v2.17.0 (from official release tarball), self-reporting as 2.16.0
- JDK version: OpenJDK 17
- Operating System: Embedded Linux on custom hardware
- Platform: ARM64 / aarch64
Additional context
The per-release fix is a one-line change in two files:
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
<groupId>com.aws.greengrass</groupId>
<artifactId>aws.greengrass.nucleus</artifactId>
- <version>2.16.0-SNAPSHOT</version>
+ <version>2.17.0</version>
--- a/conf/recipe.yaml
+++ b/conf/recipe.yaml
@@ -9,7 +9,7 @@
RecipeFormatVersion: '2020-01-25'
ComponentName: aws.greengrass.Nucleus
-ComponentVersion: '2.16.0'
+ComponentVersion: '2.17.0'
ComponentType: aws.greengrass.nucleus
Longer-term, the release pipeline should bump both files to the release tag before tagging — e.g. mvn versions:set -DnewVersion=${TAG} for pom.xml and a simple sed (or equivalent) for conf/recipe.yaml. This should run as a release-only commit, after which the development branch can be bumped back to ${NEXT}-SNAPSHOT. Standard Maven release-plugin flow handles this automatically.
I have applied this patch in our custom build pipeline and the resulting image:
- Reports
coreVersion: 2.17.0 to cloud
- Creates only
packages/nucleus/aws.greengrass.Nucleus/2.17.0/ (no spurious 2.16.0/ directory)
- Logs
version=2.17.0 consistently
Impact
-
FSS / fleet visibility: Devices that build the Nucleus from source release tarballs report a version that does not match what was downloaded. Operators tracking fleet versions in CloudWatch Logs, FSS dashboards, and aws greengrassv2 get-core-device output cannot trust the reported version.
-
Image-managed deployments (custom OS images, container images, golden images): For users who ship the Nucleus as part of an immutable OS image, the directory split between the tag directory and the metadata-version directory creates confusion about which path holds the "real" Nucleus and complicates persistent-storage strategies (e.g., when /greengrass/v2/packages/ is on a writable overlay).
-
Supply chain / CRA / Cyber Resilience Act compliance: For EU users subject to CRA Art. 13/14 audit requirements, the mismatch between published release version and binary self-reported version is a non-trivial inventory accuracy issue. Audit logs say "running 2.17.0", device says "running 2.16.0".
-
Differentiation from real downgrades: This bug masks real version-downgrade incidents. If a cloud-side bug or operator error ever does cause an actual downgrade, operators have no way to distinguish it from this metadata issue.
-
Maven artifact lifecycle: The -SNAPSHOT suffix in pom.xml has a specific semantic meaning in Maven (a development build, expected to change without warning). Shipping -SNAPSHOT in a tagged release breaks the Maven contract and would prevent any downstream Maven-based consumer from treating the artifact as a stable dependency.
Describe the bug
The published v2.17.0 source release tarball of
aws-greengrass-nucleuscontains stale version metadata in two files:pom.xmlline 7:<version>2.16.0-SNAPSHOT</version>conf/recipe.yamlline 12:ComponentVersion: '2.16.0'This is not a one-off slip — it is systematic across at least four consecutive releases. The version metadata in every release tarball from v2.15.1 through v2.17.0 lags one or two versions behind the actual release tag:
pom.xml<version>conf/recipe.yamlComponentVersion2.15.0-SNAPSHOT'2.15.0'2.16.0-SNAPSHOT'2.15.0'2.16.0-SNAPSHOT'2.16.0'2.16.0-SNAPSHOT'2.16.0'Note the
-SNAPSHOTsuffix in everypom.xml— this is a development-build marker in Maven semantics, never expected to appear in a tagged release.As a result, devices that build the Nucleus from source release tarballs (Yocto, custom OS images, container builds, anyone consuming the release zip rather than the installer scripts) end up running a Nucleus that internally self-reports a version which does not match the release they downloaded.
Steps to reproduce
The releases are not byte-identical; the bug is solely that version metadata is never bumped as part of the release process.
Expected behavior
The v2.17.0 release tarball should have version metadata matching the release tag:
pom.xmlshould have<version>2.17.0</version>(no-SNAPSHOT)conf/recipe.yamlshould haveComponentVersion: '2.17.0'Similarly for every previous release.
Actual behavior
When Nucleus is started from the v2.17.0 release tarball, it self-reports
version=2.16.0. Specifically:Kernel.javareadscomponentRecipe.getVersion()fromconf/recipe.yaml→ returns2.16.0.packages/nucleus/aws.greengrass.Nucleus/2.16.0/directory alongside any2.17.0/directory present on disk and copies its own artifacts into it, based on the recipe version.coreVersion: 2.16.0to AWS IoT Greengrass cloud.setenv.GGC_VERSIONis set to2.16.0.Reproducible Nucleus log line on a fresh install from the v2.17.0 zip:
I confirmed this is local to the device (not a cloud-side downgrade) by reproducing the directory split with the device disconnected from the internet — the
2.16.0/directory is created locally by the Nucleus on startup based onrecipe.yamlcontent.Environment
Additional context
The per-release fix is a one-line change in two files:
Longer-term, the release pipeline should bump both files to the release tag before tagging — e.g.
mvn versions:set -DnewVersion=${TAG}forpom.xmland a simplesed(or equivalent) forconf/recipe.yaml. This should run as a release-only commit, after which the development branch can be bumped back to${NEXT}-SNAPSHOT. Standard Maven release-plugin flow handles this automatically.I have applied this patch in our custom build pipeline and the resulting image:
coreVersion: 2.17.0to cloudpackages/nucleus/aws.greengrass.Nucleus/2.17.0/(no spurious2.16.0/directory)version=2.17.0consistentlyImpact
FSS / fleet visibility: Devices that build the Nucleus from source release tarballs report a version that does not match what was downloaded. Operators tracking fleet versions in CloudWatch Logs, FSS dashboards, and
aws greengrassv2 get-core-deviceoutput cannot trust the reported version.Image-managed deployments (custom OS images, container images, golden images): For users who ship the Nucleus as part of an immutable OS image, the directory split between the tag directory and the metadata-version directory creates confusion about which path holds the "real" Nucleus and complicates persistent-storage strategies (e.g., when
/greengrass/v2/packages/is on a writable overlay).Supply chain / CRA / Cyber Resilience Act compliance: For EU users subject to CRA Art. 13/14 audit requirements, the mismatch between published release version and binary self-reported version is a non-trivial inventory accuracy issue. Audit logs say "running 2.17.0", device says "running 2.16.0".
Differentiation from real downgrades: This bug masks real version-downgrade incidents. If a cloud-side bug or operator error ever does cause an actual downgrade, operators have no way to distinguish it from this metadata issue.
Maven artifact lifecycle: The
-SNAPSHOTsuffix inpom.xmlhas a specific semantic meaning in Maven (a development build, expected to change without warning). Shipping-SNAPSHOTin a tagged release breaks the Maven contract and would prevent any downstream Maven-based consumer from treating the artifact as a stable dependency.