You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Auto-generated thumbnails placed in gathered_assertions (inherited from c2pa-rs) #257
When using c2pa-python's Builder API with auto-thumbnail generation enabled
(the default), the resulting C2PA manifest places the claim thumbnail in gathered_assertions instead of created_assertions. This violates C2PA spec
section 14.3, which requires signer-originated assertions in created_assertions.
In c2pa-rs/sdk/src/builder.rs, the add_assertion helper for auto-generated
thumbnails is called with created=false, routing them to gathered_assertions.
Workaround
Option A: Disable auto-thumbnails and add them manually (loses the
convenience of auto-generation):
Neither workaround should be necessary. The library should place its own
auto-generated assertions in created_assertions by default.
Impact
C2PA Conformance Program submissions using c2pa-python will fail review if
thumbnails are enabled. Thumbnails are optional (spec section 17.1), so
disabling them is a valid short-term fix, but conforming implementations
should be able to include thumbnails without manual routing configuration.
Therefore I will defer the bug fix to the c2pa-rs repo, and it will go into the Python SDK once the root cause is fixed in the core Rust SDK.
For now, I will also keep this report open here since you mention workarounds, and to track once a release has a fix for this, leading to a Python SDK update.
Having the report in one place makes it much easier for us to track, investigate, and resolve efficiently, so we don't split the discussion. Thank you.
Status update with verification on current releases, since this issue is tracking the Python side.
Reproduced on the latest published release: c2pa-python 0.37.6 (native SDK 0.90.8), Python 3.13, default settings, manifest containing a c2pa.actions assertion with c2pa.created. Result: created_assertions contains only c2pa.hash.data; gathered_assertions contains c2pa.thumbnail.claim (and c2pa.actions.v2, which callers can opt out of per assertion with "created": true).
The code path is unchanged in c2pa-rs on both the c2pa-v0.90.10 tag (the version currently pinned in c2pa-native-version.txt) and main as of 2026-08-11 (97f27e9). In Builder::to_claim (sdk/src/builder.rs), the auto-generated claim thumbnail is added with created set to false:
// todo: add setting for created added thumbnailsadd_assertion(&mut claim,&thumbnail,false)?;
which routes through Claim::add_assertion into Claim::claim_assertion_type (sdk/src/claim.rs). For claim v2, c2pa.thumbnail.claim is not in HASH_LABELS and no created flag is set, so it lands in gathered_assertions unless builder.created_assertion_labels overrides it. The Python package does no assertion routing of its own (it is a ctypes binding over the prebuilt c2pa_c library), so there is nothing to fix in this repo; the fix will arrive via a c2pa-rs release plus a native version bump here, as noted above.
One caution on the settings workaround documented above: I verified that builder.created_assertion_labels with ["c2pa.thumbnail.claim"] does move the thumbnail into created_assertions on 0.37.6, but it is inserted at created_assertions[0], before the actions assertion. That violates the inception_action_position conformance requirement (spec section 18.14.2), which is exactly what contentauth/c2pa-rs#2238 reports from the same call site. So the workaround trades one conformance finding for another. Until the core fix lands, the option that avoids both findings for generator products is disabling auto thumbnails (builder.thumbnail.enabled = false).
For the c2pa-rs fix itself (discussion in contentauth/c2pa-rs#2106 per the maintainers): a plain false to true flip at that call site would reproduce the contentauth/c2pa-rs#2238 ordering problem, because the thumbnail block runs before the manifest assertions loop in to_claim. Moving the thumbnail add to after the assertions loop and adding it as a created assertion would resolve both issues at once, optionally gated by a new ThumbnailSettings field defaulting to created, which is what the existing TODO comment anticipates.
Activity
tmathern commentedon May 2, 2026
Thanks for the report. I see you also opened contentauth/c2pa-rs#2106 to fix the root cause.
Therefore I will defer the bug fix to the c2pa-rs repo, and it will go into the Python SDK once the root cause is fixed in the core Rust SDK.
For now, I will also keep this report open here since you mention workarounds, and to track once a release has a fix for this, leading to a Python SDK update.
tmathern commentedon May 2, 2026
For further discussions or details, please add to contentauth/c2pa-rs#2106.
Having the report in one place makes it much easier for us to track, investigate, and resolve efficiently, so we don't split the discussion. Thank you.
github-jira-sync-bot commentedon Jun 24, 2026
✅ Jira issue https://jira.corp.adobe.com/browse/CAI-12741 is successfully created for this GitHub issue.
beeswaxpat commentedon Aug 11, 2026
Status update with verification on current releases, since this issue is tracking the Python side.
Reproduced on the latest published release: c2pa-python 0.37.6 (native SDK 0.90.8), Python 3.13, default settings, manifest containing a c2pa.actions assertion with c2pa.created. Result: created_assertions contains only c2pa.hash.data; gathered_assertions contains c2pa.thumbnail.claim (and c2pa.actions.v2, which callers can opt out of per assertion with "created": true).
The code path is unchanged in c2pa-rs on both the c2pa-v0.90.10 tag (the version currently pinned in c2pa-native-version.txt) and main as of 2026-08-11 (97f27e9). In Builder::to_claim (sdk/src/builder.rs), the auto-generated claim thumbnail is added with created set to false:
which routes through Claim::add_assertion into Claim::claim_assertion_type (sdk/src/claim.rs). For claim v2, c2pa.thumbnail.claim is not in HASH_LABELS and no created flag is set, so it lands in gathered_assertions unless builder.created_assertion_labels overrides it. The Python package does no assertion routing of its own (it is a ctypes binding over the prebuilt c2pa_c library), so there is nothing to fix in this repo; the fix will arrive via a c2pa-rs release plus a native version bump here, as noted above.
One caution on the settings workaround documented above: I verified that builder.created_assertion_labels with ["c2pa.thumbnail.claim"] does move the thumbnail into created_assertions on 0.37.6, but it is inserted at created_assertions[0], before the actions assertion. That violates the inception_action_position conformance requirement (spec section 18.14.2), which is exactly what contentauth/c2pa-rs#2238 reports from the same call site. So the workaround trades one conformance finding for another. Until the core fix lands, the option that avoids both findings for generator products is disabling auto thumbnails (builder.thumbnail.enabled = false).
For the c2pa-rs fix itself (discussion in contentauth/c2pa-rs#2106 per the maintainers): a plain false to true flip at that call site would reproduce the contentauth/c2pa-rs#2238 ordering problem, because the thumbnail block runs before the manifest assertions loop in to_claim. Moving the thumbnail add to after the assertions loop and adding it as a created assertion would resolve both issues at once, optionally gated by a new ThumbnailSettings field defaulting to created, which is what the existing TODO comment anticipates.