1:"$Sreact.fragment"
2:I[15579,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],"Navigation"]
3:I[3013,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],""]
15:I[41451,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],"Footer"]
16:I[47913,["/_next/static/chunks/316a3a63422f35de.js"],"OutletBoundary"]
17:"$Sreact.suspense"
:HL["/blog/posts/gke-docker-auth-expiry/hero.jpg","image"]
:HL["/blog/posts/logo.png","image"]
0:{"buildId":"TlpKRvbES4zzM7LeczAM7","rsc":["$","$1","c",{"children":[[["$","$L2",null,{}],["$","main",null,{"className":"pt-20 md:pt-24","children":["$","article",null,{"children":[["$","header",null,{"className":"border-b border-border","children":["$","div",null,{"className":"container mx-auto px-6 py-14 md:py-20","children":[["$","$L3",null,{"href":"/blog","className":"mb-8 inline-flex items-center text-sm font-medium text-muted-foreground transition-colors hover:text-foreground","children":[["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-left mr-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1l729n",{"d":"m12 19-7-7 7-7"}],["$","path","x3x0zl",{"d":"M19 12H5"}],"$undefined"]}],"Blog"]}],["$","div",null,{"className":"grid gap-8 md:grid-cols-[1fr_0.9fr] md:items-start","children":[["$","div",null,{"className":"max-w-3xl","children":[["$","div",null,{"className":"mb-5 flex flex-wrap items-center gap-3 text-sm text-muted-foreground","children":[["$","span",null,{"className":"rounded-md border border-primary/40 bg-primary/10 px-2.5 py-1 text-primary","children":"Infrastructure"}],["$","span",null,{"children":"2026-W18"}],["$","span",null,{"aria-hidden":"true","children":"/"}],["$","span",null,{"children":"3 min read"}],[["$","span",null,{"aria-hidden":"true","children":"/"}],["$","span",null,{"children":["by ",["$","span",null,{"className":"font-medium text-foreground","children":"delve"}]]}]]]}],["$","h1",null,{"className":"text-4xl font-bold leading-tight text-balance md:text-6xl","children":"GKE Artifact Registry Auth Expiry — The Silent Push Failure"}],["$","p",null,{"className":"mt-6 text-lg leading-relaxed text-muted-foreground md:text-xl","children":"Docker's exit code after a push is not a reliable success signal when GCP auth tokens expire mid-build. The only ground truth is a registry-side digest check."}]]}],["$","div",null,{"className":"overflow-hidden rounded-lg border border-border bg-card","children":["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden","children":[null,["$","img",null,{"src":"/blog/posts/gke-docker-auth-expiry/hero.jpg","alt":"A vintage parking meter showing 'EXPIRED' in its window against a moody urban backdrop.","className":"h-full w-full object-cover"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-4 top-4 h-[50px] w-[50px] mix-blend-screen"}]]}]}]]}]]}]}],["$","div",null,{"className":"container mx-auto px-6 py-12 md:py-16","children":["$","div",null,{"className":"grid gap-10 lg:grid-cols-[minmax(0,1fr)_280px] lg:items-start","children":[["$","div",null,{"className":"max-w-3xl text-muted-foreground","children":[[["$","h2","h2-0",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"The problem"}],"\n",["$","p","p-0",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["Google Artifact Registry auth tokens expire after one hour. If you run a long build session — say, a Docker build that takes 20 minutes followed by a push — and your ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"gcloud auth configure-docker"}]," was done at the start of the session, the push can fail with ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"denied: Unauthenticated request"}]," even though the build succeeded. The worse case: ",["$","code","code-2",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"docker push"}]," reports a successful layer push but the final manifest push fails, and the overall command exits 0 because the layers were cached. The image appears to push. It didn't."]}],"\n","$L4","\n","$L5","\n","$L6","\n","$L7","\n","$L8","\n","$L9","\n","$La","\n","$Lb","\n","$Lc"],"$Ld",null]}],"$Le"]}]}]]}]}],"$Lf"],["$L10","$L11","$L12"],"$L13"]}],"loading":null,"isPartial":false}
4:["$","p","p-1",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["The downstream symptom is ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"ImagePullBackOff"}]," on ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"kubectl rollout"}]," — a confusing error that reads like a pull problem rather than a push problem."]}]
5:["$","h2","h2-1",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"The approach"}]
6:["$","p","p-2",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"The reliable pattern is to re-authenticate immediately before every push, not once at the start of a session:"}]
7:["$","div","pre-0",{"style":{"background":"hsl(220, 13%, 18%)","color":"hsl(220, 14%, 71%)","textShadow":"0 1px rgba(0, 0, 0, 0.3)","fontFamily":"\"Fira Code\", \"Fira Mono\", Menlo, Consolas, \"DejaVu Sans Mono\", monospace","direction":"ltr","textAlign":"left","whiteSpace":"pre","wordSpacing":"normal","wordBreak":"normal","lineHeight":"1.5","MozTabSize":"2","OTabSize":"2","tabSize":"2","WebkitHyphens":"none","MozHyphens":"none","msHyphens":"none","hyphens":"none","padding":"1rem","margin":"0.5em 0","overflow":"auto","borderRadius":"0.5rem","marginTop":"1.25rem","marginBottom":0,"border":"1px solid hsl(var(--border))","fontSize":"0.875rem"},"children":["$","code",null,{"style":{"whiteSpace":"pre","fontFamily":"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace"},"children":[false,[["$","span","code-segment-0",{"style":{},"children":["gcloud auth configure-docker asia-southeast1-docker.pkg.dev "]}],["$","span","code-segment-1",{"className":"token parameter","style":{"color":"hsl(207, 82%, 66%)"},"children":["--quiet"]}],["$","span","code-segment-2",{"style":{},"children":["\n"]}],["$","span","code-segment-3",{"style":{},"children":["gcloud auth print-access-token "]}],["$","span","code-segment-4",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["|"]}],["$","span","code-segment-5",{"style":{},"children":[" "]}],["$","span","code-segment-6",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["docker"]}],["$","span","code-segment-7",{"style":{},"children":[" login "]}],["$","span","code-segment-8",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["\\"]}],["$","span","code-segment-9",{"style":{},"children":["\n"]}],["$","span","code-segment-10",{"style":{},"children":["  "]}],["$","span","code-segment-11",{"className":"token parameter","style":{"color":"hsl(207, 82%, 66%)"},"children":["-u"]}],["$","span","code-segment-12",{"style":{},"children":[" oauth2accesstoken "]}],["$","span","code-segment-13",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["\\"]}],["$","span","code-segment-14",{"style":{},"children":["\n"]}],["$","span","code-segment-15",{"style":{},"children":["  --password-stdin "]}],["$","span","code-segment-16",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["\\"]}],["$","span","code-segment-17",{"style":{},"children":["\n"]}],"  asia-southeast1-docker.pkg.dev\n","\n",["$","span","code-segment-20",{"style":{},"children":[""]}],["$","span","code-segment-21",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["docker"]}],["$","span","code-segment-22",{"style":{},"children":[" push asia-southeast1-docker.pkg.dev/project/repo/image:tag\n"]}],"\n",["$","span","code-segment-24",{"style":{},"children":[""]}],["$","span","code-segment-25",{"className":"token","style":{"color":"hsl(220, 10%, 40%)","fontStyle":"italic"},"children":["# Verify the push actually landed — don't trust exit code alone"]}],["$","span","code-segment-26",{"style":{},"children":["\n"]}],["$","span","code-segment-27",{"style":{},"children":["gcloud artifacts "]}],["$","span","code-segment-28",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["docker"]}],["$","span","code-segment-29",{"style":{},"children":[" images describe "]}],["$","span","code-segment-30",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["\\"]}],["$","span","code-segment-31",{"style":{},"children":["\n"]}],["$","span","code-segment-32",{"style":{},"children":["  asia-southeast1-docker.pkg.dev/project/repo/image:tag "]}],["$","span","code-segment-33",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["\\"]}],["$","span","code-segment-34",{"style":{},"children":["\n"]}],["$","span","code-segment-35",{"style":{},"children":["  "]}],["$","span","code-segment-36",{"className":"token parameter","style":{"color":"hsl(207, 82%, 66%)"},"children":["--format"]}],["$","span","code-segment-37",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["="]}],["$","span","code-segment-38",{"className":"token","style":{"color":"hsl(95, 38%, 62%)"},"children":["\"value(image_summary.digest)\""]}]]]}]}]
8:["$","p","p-3",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["The ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"gcloud auth print-access-token | docker login"}]," approach uses a fresh short-lived token rather than the credential helper, which can cache a stale token. The final ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"gcloud artifacts docker images describe"}]," confirms the digest is live in the registry — this is the only reliable proof the push succeeded."]}]
9:["$","p","p-4",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["For ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"kubectl set image"}]," deployments, always follow with ",["$","code","code-1",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"kubectl rollout status"}]," and watch for ",["$","code","code-2",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"ImagePullBackOff"}]," before declaring success:"]}]
a:["$","div","pre-1",{"style":{"background":"hsl(220, 13%, 18%)","color":"hsl(220, 14%, 71%)","textShadow":"0 1px rgba(0, 0, 0, 0.3)","fontFamily":"\"Fira Code\", \"Fira Mono\", Menlo, Consolas, \"DejaVu Sans Mono\", monospace","direction":"ltr","textAlign":"left","whiteSpace":"pre","wordSpacing":"normal","wordBreak":"normal","lineHeight":"1.5","MozTabSize":"2","OTabSize":"2","tabSize":"2","WebkitHyphens":"none","MozHyphens":"none","msHyphens":"none","hyphens":"none","padding":"1rem","margin":"0.5em 0","overflow":"auto","borderRadius":"0.5rem","marginTop":"1.25rem","marginBottom":0,"border":"1px solid hsl(var(--border))","fontSize":"0.875rem"},"children":["$","code",null,{"style":{"whiteSpace":"pre","fontFamily":"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace"},"children":[false,[["$","span","code-segment-0",{"style":{},"children":["kubectl "]}],["$","span","code-segment-1",{"className":"token","style":{"color":"hsl(29, 54%, 61%)"},"children":["set"]}],["$","span","code-segment-2",{"style":{},"children":[" image deployment/my-app "]}],["$","span","code-segment-3",{"className":"token assign-left","style":{"color":"hsl(207, 82%, 66%)"},"children":["container"]}],["$","span","code-segment-4",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["="]}],["$","span","code-segment-5",{"style":{},"children":["image:tag\n"]}],["$","span","code-segment-6",{"style":{},"children":["kubectl rollout status deployment/my-app "]}],["$","span","code-segment-7",{"className":"token parameter","style":{"color":"hsl(207, 82%, 66%)"},"children":["--timeout"]}],["$","span","code-segment-8",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["="]}],["$","span","code-segment-9",{"style":{},"children":["3m"]}]]]}]}]
b:["$","h2","h2-2",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"What I learned"}]
c:["$","p","p-5",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"Docker's exit code after a push is not a reliable success signal when auth issues are involved. The layers are pushed first (and they may already be cached in the registry), and the final manifest write is what requires a valid auth token. If the token expired between layer push and manifest commit, docker may report partial success or exit 0 depending on the exact timing and caching state. The only ground truth is a registry-side digest check. This is especially relevant in background build jobs where the auth was established before the job started."}]
d:["$","div",null,{"className":"mt-14 border-t border-border pt-8","children":["$","$L3",null,{"href":"/platform","className":"inline-flex items-center text-sm font-medium text-primary transition-colors hover:text-primary/80","children":["Start a build",["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-right ml-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1ays0h",{"d":"M5 12h14"}],["$","path","xquz4c",{"d":"m12 5 7 7-7 7"}],"$undefined"]}]]}]}]
e:["$","aside",null,{"className":"hidden lg:block","children":["$","div",null,{"className":"sticky top-24 space-y-4","children":[["$","h3",null,{"className":"text-xs font-semibold uppercase tracking-wider text-primary","children":["More in ","Infrastructure"]}],["$","div",null,{"className":"space-y-4","children":[["$","$L3","criu-tcp-repair-live-migration",{"href":"/blog/criu-tcp-repair-live-migration","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/criu-tcp-repair-live-migration/hero.jpg","alt":"A bird in mid-flight viewed from below against a clean grey sky, wings extended.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Infrastructure"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W19"," · ","4 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"Freezing Live TCP Connections for Process Migration with CRIU"}]]}]]}],["$","$L3","mac-address-as-portable-identity",{"href":"/blog/mac-address-as-portable-identity","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/mac-address-as-portable-identity/hero.jpg","alt":"A USB Ethernet adapter on a worn wooden desk under a single warm overhead lamp, macro shot showing the gold contact pins, minimal dark background, no people, editorial.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Infrastructure"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W19"," · ","5 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"The MAC Address as Portable Machine Identity"}]]}]]}],["$","$L3","when-the-database-lies-the-kernel-doesnt",{"href":"/blog/when-the-database-lies-the-kernel-doesnt","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/when-the-database-lies-the-kernel-doesnt/hero.jpg","alt":"A black-and-white wide shot of a server rack at night with a single green LED illuminating one rack unit, cables draping like ivy down the side, no people, dramatic editorial composition.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Infrastructure"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W18"," · ","6 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"When the Database Lies, the Kernel Doesn't"}]]}]]}]]}],"$L14"]}]}]
f:["$","$L15",null,{}]
10:["$","script","script-0",{"src":"/_next/static/chunks/94245cbda44972fe.js","async":true}]
11:["$","script","script-1",{"src":"/_next/static/chunks/af778fff4a0f4be6.js","async":true}]
12:["$","script","script-2",{"src":"/_next/static/chunks/b096b037d08e2f31.js","async":true}]
13:["$","$L16",null,{"children":["$","$17",null,{"name":"Next.MetadataOutlet","children":"$@18"}]}]
14:["$","$L3",null,{"href":"/blog?category=infrastructure","className":"inline-flex items-center text-sm font-medium text-primary transition-colors hover:text-primary/80","children":["Read all in ","Infrastructure",["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-right ml-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1ays0h",{"d":"M5 12h14"}],["$","path","xquz4c",{"d":"m12 5 7 7-7 7"}],"$undefined"]}]]}]
18:null
