benbjohnson/litestream · error
heartbeat interval must be at least 1 minute
Error message
heartbeat interval must be at least 1 minute
What it means
ErrInvalidHeartbeatInterval is returned by Config.Validate when heartbeat-interval is set below litestream.MinHeartbeatInterval (1 minute). Heartbeats are low-frequency liveness signals, so sub-minute intervals are rejected to avoid hammering the target endpoint.
Source
Thrown at cmd/litestream/main.go:62
bi, _ := debug.ReadBuildInfo()
Version = resolveVersion(Version, bi)
}
// errStop is a terminal error for indicating program should quit.
var errStop = errors.New("stop")
// Sentinel errors for configuration validation
var (
ErrInvalidSnapshotInterval = errors.New("snapshot interval must be greater than 0")
ErrInvalidSnapshotRetention = errors.New("snapshot retention must be greater than 0")
ErrInvalidCompactionInterval = errors.New("compaction interval must be greater than 0")
ErrInvalidSyncInterval = errors.New("sync interval must be greater than 0")
ErrInvalidL0Retention = errors.New("l0 retention must not be negative")
ErrInvalidL0RetentionCheckInterval = errors.New("l0 retention check interval must be greater than 0")
ErrInvalidShutdownSyncTimeout = errors.New("shutdown-sync-timeout must be >= 0")
ErrInvalidShutdownSyncInterval = errors.New("shutdown sync interval must be greater than 0")
ErrInvalidHeartbeatURL = errors.New("heartbeat URL must be a valid HTTP or HTTPS URL")
ErrInvalidHeartbeatInterval = errors.New("heartbeat interval must be at least 1 minute")
ErrConfigFileNotFound = errors.New("config file not found")
)
// ConfigValidationError wraps a validation error with additional context
type ConfigValidationError struct {
Err error
Field string
Value interface{}
}
func (e *ConfigValidationError) Error() string {
if e.Value != nil {
return fmt.Sprintf("%s: %v (got %v)", e.Field, e.Err, e.Value)
}
return fmt.Sprintf("%s: %v", e.Field, e.Err)
}
func (e *ConfigValidationError) Unwrap() error {View on GitHub (pinned to 4ed7a308f6)
Solutions
- Set heartbeat-interval to at least 1m (e.g. 5m)
- Check the duration unit suffix — Go durations need s/m/h, a bare number is nanoseconds
- Remove heartbeat-interval to use the default interval
Example fix
# before heartbeat-interval: 30s # after heartbeat-interval: 5m
Defensive patterns
Strategy: validation
Validate before calling
if hb != "" {
d, err := time.ParseDuration(hb)
if err != nil || d < time.Minute {
return fmt.Errorf("heartbeat-interval must be >= 1m, got %q", hb)
}
} Prevention
- Remember Go duration syntax requires units: write 5m not 300
- Treat 1 minute as the floor when generating configs
- Validate durations in CI before rolling out config changes
When it happens
Trigger: Setting heartbeat-interval in the config to a duration smaller than 1m (e.g. 30s, 10s, 500ms) — detected in Validate via *c.HeartbeatInterval < litestream.MinHeartbeatInterval.
Common situations: Users assuming heartbeat frequency should match sync-interval granularity and writing "30s", or misparsing the duration unit ("1" meaning 1 minute but parsed as 1 nanosecond).
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- invalid sync_interval: %w
- invalid poll_interval: %w
- heartbeat URL must be a valid HTTP or HTTPS URL
- database config #%d: duplicate path %q (already used by data
- database config #%d: 'pattern' is required when using 'dir'
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/cc53af96c505c12b.
Report an issue: GitHub.