microsoft/aspire · critical · InvalidOperationException
ASPIRERADIUS063
ASPIRERADIUS063
Error message
Secret store '{storeName}' references a SealedSecret manifest at '{manifestPath}' whose '{LastAppliedConfigurationAnnotation}' annotation embeds a plaintext Kubernetes Secret (kind 'Secret' with 'data'/'stringData'), or content that cannot be verified as sealed. Such annotations are copied verbatim into publish artifacts and applied to the cluster, so the cleartext would leak. Re-seal from a clean manifest without the annotation. Diagnostic: ASPIRERADIUS063. What it means
The sealed-secrets workflow can leave a last-applied-configuration annotation embedding the original plaintext Secret JSON (with data/stringData). Since Aspire copies the SealedSecret manifest verbatim into publish artifacts, such an annotation would leak cleartext credentials; validation fails closed when the annotation exists and either is not a JSON string scalar or embeds a plaintext Secret.
Solutions
- Remove the last-applied-configuration annotation from the SealedSecret and re-seal from a clean manifest.
- Re-generate with kubeseal from a fresh source Secret: 'kubectl create secret generic x --from-literal=... -o yaml --dry-run=client | kubeseal -o yaml > sealed.yaml' (dry-run output carries no recorded annotation).
- If the annotation is intentionally non-secret JSON that fails the check, remove it anyway — the validator cannot verify it is sealed and fails closed.
Example fix
// before (metadata.annotations contains)
kubectl.kubernetes.io/last-applied-configuration: '{"kind":"Secret","data":{"password":"cGFzcw=="}}'
// after
metadata:
name: my-secret # annotation removed; re-sealed from clean manifest Defensive patterns
Strategy: validation
Validate before calling
var annotations = doc["metadata"]?["annotations"];
if (annotations?["kubectl.kubernetes.io/last-applied-configuration"] is { }) throw new InvalidOperationException("SealedSecret embeds last-applied-configuration annotation; re-seal from a clean manifest."); Type guard
bool HasLastAppliedAnnotation(YamlNode root) => root is YamlMappingNode m && m["metadata"] is YamlMappingNode md && md["annotations"] is YamlMappingNode a && a.Children.ContainsKey(new YamlScalarNode("kubectl.kubernetes.io/last-applied-configuration")); Try / catch
try { store = ReadValidated(...); } catch (InvalidOperationException ex) when (ex.Message.Contains("ASPIRERADIUS063")) { // strip the annotation and re-seal; do NOT commit the manifest } Prevention
- Create sealed secrets from 'kubectl create ... --dry-run=client -o yaml | kubeseal' so no last-applied annotation is recorded.
- Never kubectl-apply plaintext Secrets into the objects you later seal.
- Scan sealed manifests for 'last-applied-configuration' in CI.
When it happens
Trigger: CheckLastAppliedAnnotation (called by RejectPlaintextLastAppliedAnnotation during manifest validation) finds the last-applied-configuration annotation whose value is not a plain JSON string scalar, or whose embedded JSON contains a 'Secret' kind with data/stringData.
Common situations: Manifest created by 'kubectl apply -f secret.yaml && kubeseal' without cleaning the recorded annotation (kubectl apply records it), or an annotation value that is a YAML mapping/null rather than a JSON string.
Related errors
- ASPIRERADIUS058
- ASPIRERADIUS061
- Credential-bearing HTTP sources cannot be persisted.
- Secret store ' ' references a manifest at ' ' that contains…
- Secret store ' ' references a manifest at ' ' that contains…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/c46ebff8e8009c7d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Radius/Secrets/SealedSecretManifest.cs:351
}
private static void CheckLastAppliedAnnotation(
string storeName, string manifestPath, YamlMappingNode owner)
{
if (!TryGetNode(owner, "metadata", out var metadataNode) || metadataNode is not YamlMappingNode metadata ||
!TryGetNode(metadata, "annotations", out var annotationsNode) || annotationsNode is not YamlMappingNode annotations ||
!TryGetNode(annotations, LastAppliedConfigurationAnnotation, out var valueNode))
{
return;
}
// The annotation is present. A legitimate value is always a JSON string scalar (Kubernetes
// annotation values are `map[string]string`). Anything else — a YAML mapping/sequence, or a
// null/empty scalar where we expected JSON — cannot be verified free of cleartext, so fail
// closed rather than skip it.
if (valueNode is not YamlScalarNode { Value: { } lastApplied } || EmbedsPlaintextSecret(lastApplied))
{
throw new InvalidOperationException(
$"Secret store '{storeName}' references a SealedSecret manifest at '{manifestPath}' whose " +
$"'{LastAppliedConfigurationAnnotation}' annotation embeds a plaintext Kubernetes Secret " +
"(kind 'Secret' with 'data'/'stringData'), or content that cannot be verified as sealed. Such " +
"annotations are copied verbatim into publish artifacts and applied to the cluster, so the " +
"cleartext would leak. Re-seal from a clean manifest without the annotation. " +
"Diagnostic: ASPIRERADIUS063.");
}
}
// Example annotation value (a single JSON string):
// {"apiVersion":"v1","kind":"Secret","metadata":{...},"data":{"password":"cGFzcw=="}}
// Returns true when that JSON is a plaintext Secret carrying data/stringData, or when it cannot
// be parsed as the expected object (fail closed). An embedded SealedSecret returns false.
private static bool EmbedsPlaintextSecret(string lastAppliedJson)
{
try
{
using var document = JsonDocument.Parse(lastAppliedJson);View on GitHub (pinned to 25830f84bd)