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
MASQUE: a grant the authority renews after core stopped it leaves the adopted attachment refused #1236
A connector's authorization (its EdgeService) is valid until validUntil, at most 28 s after the last authorize or refresh. Core and galactic-edge stop it 2 s (MaxSkew) before that, and core refuses the connector's attachment with GrantExpired. The grant authority, however, treats the incarnation as live until validUntil itself.
If the connector's next request arrives inside that 2 s window, the authority renews the incarnation in place, so the service's validUntil moves forward under the same UID. Core does not re-admit the attachment it already refused, and the provider adapter fails each request at once with attachment_failed (GrantExpired) on that refused attachment instead of replacing it. The connector gets 503 on every request until the attachment goes away, about 30 s in the lab, although its credential and authorization are valid throughout.
How it was seen
In the containerlab gVPC lab, with the MASQUE service and grant authority from config/masque:
Two connectors forward through one provider pod.
The provider process is killed with SIGKILL. The kubelet restarts it in the same pod, and the new process adopts the pod's attachments, then waits about 17 s for the old process's lease to expire.
One connector's next request reached the authority 1 to 2 s before its incarnation's validUntil.
The provider then logged, every 2 s for 31 s:
admission refused outcome=attachment_failed vpc=ns20/20 error="masque: connector unavailable: connector <id>: attachment ea-<pod>-<service> refused: GrantExpired: grant <service> expired at <validUntil>"
The EdgeService kept its UID across these requests. The connector was served again only after the attachment was requested anew.
The window is narrow and depends on timing: in five runs of the same row it happened once. It is not specific to a process restart. Any connector whose next request lands within MaxSkew of its idle incarnation's validUntil can hit it.
Expected
A request whose authorization the authority renews is admitted, or the authority refuses to renew an incarnation core has already stopped and issues a new one. Either way the connector should not get 503s for the attachment's idle period while its grant is valid.
Possible fixes:
The authority treats an incarnation within MaxSkew of validUntil as expired: it retires it and issues a successor, as it does after validUntil.
The adapter deletes an attachment core refused with GrantExpired and requests a new one when a renewed grant arrives.
Related
Found while running the MASQUE service lab rows for #980 and #976. The lab's process-restart row reconnects as soon as the new process holds its lease, so it stays clear of this window.
A second, deterministic way to hit this in the lab: stop the grant authority's process while a connector forwards. The request ends at the grant's deadline, the authority's sweep is stopped too, so the incarnation is never retired. Once the authority resumes, it renews the same incarnation in place, and every request of the connector for the next 31 s got attachment_failed with GrantExpired on the old attachment, until the adapter deleted it and requested a new one.
Activity
privateip commentedon Oct 29, 2026
A second, deterministic way to hit this in the lab: stop the grant authority's process while a connector forwards. The request ends at the grant's deadline, the authority's sweep is stopped too, so the incarnation is never retired. Once the authority resumes, it renews the same incarnation in place, and every request of the connector for the next 31 s got
attachment_failedwithGrantExpiredon the old attachment, until the adapter deleted it and requested a new one.