tailscale/tailscale · error
can't parse expiry time, expects a unix timestamp
Error message
can't parse expiry time, expects a unix timestamp
What it means
Sent as 400 by serveSetExpirySooner when the 'expiry' parameter is present but not an integer Unix timestamp.
Source
Thrown at ipn/localapi/localapi.go:1246
}
// serveSetExpirySooner sets the expiry date on the current machine, specified
// by an `expiry` unix timestamp as POST or query param.
func (h *Handler) serveSetExpirySooner(w http.ResponseWriter, r *http.Request) {
if !h.PermitWrite {
http.Error(w, "access denied", http.StatusForbidden)
return
}
if r.Method != httpm.POST {
http.Error(w, "POST required", http.StatusMethodNotAllowed)
return
}
var expiryTime time.Time
if v := r.FormValue("expiry"); v != "" {
expiryInt, err := strconv.ParseInt(v, 10, 64)
if err != nil {
http.Error(w, "can't parse expiry time, expects a unix timestamp", http.StatusBadRequest)
return
}
expiryTime = time.Unix(expiryInt, 0)
} else {
http.Error(w, "missing 'expiry' parameter, a unix timestamp", http.StatusBadRequest)
return
}
err := h.b.SetExpirySooner(r.Context(), expiryTime)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", "text/plain")
io.WriteString(w, "done\n")
}
func (h *Handler) servePing(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()View on GitHub (pinned to 6e0912f979)
Solutions
- Pass expiry as seconds since Unix epoch (e.g. 1735689600)
- Remove quotes/whitespace from the parameter
- Validate client-side before sending
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at ipn/localapi/localapi.go:1246 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18).
Data as JSON: /api/errors/174bbaf91271cdde.
Report an issue: GitHub.