{"record":{"id":"4b6c3fec40b6ef5e","repo":"benbjohnson/litestream","slug":"heartbeat-url-must-be-a-valid-http-or-https-url","errorCode":null,"errorMessage":"heartbeat URL must be a valid HTTP or HTTPS URL","messagePattern":"heartbeat URL must be a valid HTTP or HTTPS URL","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":61,"sourceCode":"func init() {\n\tbi, _ := debug.ReadBuildInfo()\n\tVersion = resolveVersion(Version, bi)\n}\n\n// errStop is a terminal error for indicating program should quit.\nvar errStop = errors.New(\"stop\")\n\n// Sentinel errors for configuration validation\nvar (\n\tErrInvalidSnapshotInterval         = errors.New(\"snapshot interval must be greater than 0\")\n\tErrInvalidSnapshotRetention        = errors.New(\"snapshot retention must be greater than 0\")\n\tErrInvalidCompactionInterval       = errors.New(\"compaction interval must be greater than 0\")\n\tErrInvalidSyncInterval             = errors.New(\"sync interval must be greater than 0\")\n\tErrInvalidL0Retention              = errors.New(\"l0 retention must not be negative\")\n\tErrInvalidL0RetentionCheckInterval = errors.New(\"l0 retention check interval must be greater than 0\")\n\tErrInvalidShutdownSyncTimeout      = errors.New(\"shutdown-sync-timeout must be >= 0\")\n\tErrInvalidShutdownSyncInterval     = errors.New(\"shutdown sync interval must be greater than 0\")\n\tErrInvalidHeartbeatURL             = errors.New(\"heartbeat URL must be a valid HTTP or HTTPS URL\")\n\tErrInvalidHeartbeatInterval        = errors.New(\"heartbeat interval must be at least 1 minute\")\n\tErrConfigFileNotFound              = errors.New(\"config file not found\")\n)\n\n// ConfigValidationError wraps a validation error with additional context\ntype ConfigValidationError struct {\n\tErr   error\n\tField string\n\tValue interface{}\n}\n\nfunc (e *ConfigValidationError) Error() string {\n\tif e.Value != nil {\n\t\treturn fmt.Sprintf(\"%s: %v (got %v)\", e.Field, e.Err, e.Value)\n\t}\n\treturn fmt.Sprintf(\"%s: %v\", e.Field, e.Err)\n}\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L43-L79","documentation":"ErrInvalidHeartbeatURL is returned by Config.Validate when the heartbeat-url config value is set but is not a parseable HTTP or HTTPS URL. Litestream sends periodic heartbeat pings to this URL, so a malformed value would silently break monitoring; validation rejects it up front via ConfigValidationError with Field \"heartbeat-url\".","triggerScenarios":"Setting heartbeat-url in the YAML config (or the c.HeartbeatURL field) to a value that fails isValidHeartbeatURL: a scheme-less host (\"myhost/ping\"), an unsupported scheme (\"ftp://...\", \"tcp://...\"), or a string that does not parse as a URL at all.","commonSituations":"Typos like heartbeat-url: myserver:8080/ping (missing scheme), copying an internal service URL that starts with a scheme other than http/https, or quoting issues in YAML that leave stray characters in the value.","solutions":["Prefix the URL with http:// or https:// in the config","Verify the value with the URL parser you expect: it must parse and have Scheme http or https","Remove heartbeat-url entirely if you do not want heartbeats"],"exampleFix":"# before\nheartbeat-url: monitoring.internal:8080/ping\n# after\nheartbeat-url: https://monitoring.internal:8080/ping","handlingStrategy":"validation","validationCode":"func validHeartbeatURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}\n// call before writing config / at startup","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include an explicit http:// or https:// scheme in config URLs","Lint config files for URL fields at deploy time","Keep heartbeat URLs in one templated variable to avoid per-env typos"],"tags":["config","validation","http","url"],"backgroundTag":"invalid-url-format","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}