cilium/cilium · error
could not determine clocksource
Error message
could not determine clocksource
What it means
GetClockSourceFromAgent queries the cilium agent's Healthz API endpoint and expects a ClockSource object in the response. When the payload's ClockSource field is nil, the library cannot know which clock the BPF timestamps use, so it refuses to guess and returns this error. It is a defensive check against an agent that did not report its clocksource.
Source
Thrown at pkg/maps/timestamp/timestamp.go:52
}
// Get current clocksource - to be used in the agent context.
func GetClockSourceFromOptions() *models.ClockSource {
return getClockSourceFromConfig(option.Config)
}
// Connect to the agent via API and get its current clocksource.
func GetClockSourceFromAgent(svc daemon.ClientService) (*models.ClockSource, error) {
params := daemon.NewGetHealthzParamsWithTimeout(5 * time.Second)
brief := false
params.SetBrief(&brief)
resp, err := svc.GetHealthz(params)
if err != nil {
return nil, err
}
if resp.Payload.ClockSource == nil {
return nil, fmt.Errorf("could not determine clocksource")
}
return resp.Payload.ClockSource, nil
}
// Get the clocksource from the agent config file in case agent is not running.
func GetClockSourceFromRuntimeConfig() (*models.ClockSource, error) {
var config option.DaemonConfig
agentConfigFile := filepath.Join(defaults.RuntimePath, defaults.StateDir,
"agent-runtime-config.json")
if byteValue, err := os.ReadFile(agentConfigFile); err == nil {
err = json.Unmarshal(byteValue, &config)
if err != nil {
return nil, err
}
return getClockSourceFromConfig(&config), nilView on GitHub (pinned to ac7b90affa)
Solutions
- Upgrade or restart the cilium agent so its health payload includes clock_source
- Read the clocksource from the agent config file instead (the package provides a config-file path for exactly this case)
- Verify the Healthz response payload actually contains clock_source (inspect GET /healthz output)
- Ensure the Go client model (models.ClockSource) matches the agent's API version
Example fix
// before: nil propagates to converter constructors
clockSource, _ := GetClockSourceFromAgent(svc)
// after: fall back to config-file clocksource on nil
resp, err := svc.GetHealthz(params)
if err != nil {
return nil, err
}
if resp.Payload.ClockSource == nil {
return getClockSourceFromConfig() // fallback path
}
return resp.Payload.ClockSource, nil Defensive patterns
Strategy: fallback
Validate before calling
// Check the payload before trusting it
resp, _ := svc.GetHealthz(params)
hasClockSource := resp != nil && resp.Payload != nil && resp.Payload.ClockSource != nil
if !hasClockSource {
// fall back to agent config file clocksource
} Type guard
func clockSourceKnown(cs *models.ClockSource) bool {
return cs != nil && cs.Mode != ""
} Try / catch
// Go: fall back to config-file source when API yields none
clockSource, err := GetClockSourceFromAgent(svc)
if err != nil {
clockSource, err = getClockSourceFromConfig()
if err != nil {
return fmt.Errorf("no clocksource from API or config: %w", err)
}
} Prevention
- Keep agent and client API models version-aligned
- Retry health queries briefly on agent startup before giving up
- Alert on healthz payloads missing clock_source
- Prefer the config-file clocksource path in offline tooling
When it happens
Trigger: Calling GetClockSourceFromAgent against an agent whose /healthz payload has no clock_source field — e.g. an older agent version predating clocksource reporting, a partially initialized agent, or a proxied/mocked health API client returning a stale/empty payload.
Common situations: Version skew between client and agent (old agent without clocksource support); agent still starting up before config is populated; health endpoint behind a proxy that drops optional fields.
Related errors
- invalid EndpointSlicesExportMode %q
- invalid clocksource: %s
- clockSource is nil
- invalid clock Hertz value (0)
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/8f39539c73124510.
Report an issue: GitHub.