{"record":{"id":"376cc86cf459d8ba","repo":"hashicorp/packer","slug":"attestation-builder-id-q-does-not-match-expected","errorCode":null,"errorMessage":"attestation builder id %q does not match expected %q","messagePattern":"attestation builder id %q does not match expected %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/verify.go","lineNumber":256,"sourceCode":"\t}\n\n\tif policy.BuilderID != \"\" || policy.SourceURI != \"\" {\n\t\tif statement.PredicateType != internalprovenance.SLSAProvenanceV1PredicateType {\n\t\t\treturn nil, fmt.Errorf(\"builder and source policy checks require predicate type %q, got %q\", internalprovenance.SLSAProvenanceV1PredicateType, statement.PredicateType)\n\t\t}\n\n\t\tvar typedStatement struct {\n\t\t\tType          string                                     `json:\"_type\"`\n\t\t\tSubject       []internalprovenance.Subject               `json:\"subject\"`\n\t\t\tPredicateType string                                     `json:\"predicateType\"`\n\t\t\tPredicate     internalprovenance.SLSAProvenancePredicate `json:\"predicate\"`\n\t\t}\n\t\tif err := json.Unmarshal(payload, &typedStatement); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"decode SLSA predicate for policy verification: %w\", err)\n\t\t}\n\n\t\tif policy.BuilderID != \"\" && typedStatement.Predicate.RunDetails.Builder.ID != policy.BuilderID {\n\t\t\treturn nil, fmt.Errorf(\"attestation builder id %q does not match expected %q\", typedStatement.Predicate.RunDetails.Builder.ID, policy.BuilderID)\n\t\t}\n\n\t\tif policy.SourceURI != \"\" {\n\t\t\tmatched := false\n\t\t\tfor _, dependency := range typedStatement.Predicate.BuildDefinition.ResolvedDependencies {\n\t\t\t\tif dependency.URI == policy.SourceURI {\n\t\t\t\t\tmatched = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\treturn nil, fmt.Errorf(\"attestation does not contain expected source URI %q\", policy.SourceURI)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &statement, nil\n}","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/verify.go#L238-L274","documentation":"When the policy sets BuilderID, verifyPolicy compares it to predicate.runDetails.builder.id of the SLSA v1 provenance. This error means the attestation was produced by a different builder than the policy trusts.","triggerScenarios":"VerifyAttestationFile with policy.BuilderID set (e.g. \"https://github.com/actions/runner\") on an attestation whose runDetails.builder.id differs (empty or another CI system's ID).","commonSituations":"Rebuilt artifacts produced by a different CI pipeline than the one in policy; builder ID configured with wrong URI format (missing scheme or trailing difference); attestations from a fork's runner while policy pins the upstream builder.","solutions":["Check the error's two IDs: the attestation's actual builder.id versus policy expectation; fix whichever is wrong.","Update policy.BuilderID to the exact builder ID your CI emits (match URI format exactly).","Re-run the build on the builder specified in the policy and use its attestation.","If multiple builders are trusted, verify each with its own policy rather than a single BuilderID."],"exampleFix":"// before\npolicy.BuilderID = \"https://github.com/actions/runner\" // attestation says \"https://circleci.com\"\n// after\npolicy.BuilderID = \"https://circleci.com\" // or rebuild on GitHub Actions","handlingStrategy":"validation","validationCode":"var s struct {\n\tPredicate struct {\n\t\tRunDetails struct {\n\t\t\tBuilder struct{ ID string `json:\"id\"` } `json:\"builder\"`\n\t\t} `json:\"runDetails\"`\n\t} `json:\"predicate\"`\n}\n_ = json.Unmarshal(payload, &s)\nif policy.BuilderID != \"\" && s.Predicate.RunDetails.Builder.ID != policy.BuilderID {\n\treturn fmt.Errorf(\"builder %q not trusted\", s.Predicate.RunDetails.Builder.ID)\n}","typeGuard":null,"tryCatchPattern":"_, err := VerifyAttestationFile(path, policy)\nif err != nil && strings.Contains(err.Error(), \"builder id\") {\n\t// error message shows actual vs expected; update policy or rebuild on trusted builder\n}","preventionTips":["Copy BuilderID byte-for-byte from a known-good attestation's runDetails.builder.id","Keep a trust list of builder IDs and match exactly","Re-run builds on the pinned builder when provenance comes from elsewhere"],"tags":["attestation","slsa","builder-id"],"backgroundTag":"builder-id-mismatch","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}