{"record":{"id":"69ff4119c39a6a8e","repo":"caddyserver/caddy","slug":"cannot-reuse-socket-v-unix-socket-is-already-in","errorCode":null,"errorMessage":"cannot reuse socket %v: unix socket is already in use by another process","messagePattern":"cannot reuse socket (.+?): unix socket is already in use by another process","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"listen_reuseUnixSocket_windows.go","lineNumber":62,"sourceCode":"\t\t// Abstract Unix sockets do not require us to remove stale socket files.\n\t\treturn nil, nil\n\t}\n\n\t// On Windows, we're using the `fakeCloseListener` wrappers around a single, ever-living listener.\n\t// So, if there's an active listener entry in the pool, we're the current owner of the Unix socket file.\n\t_, socketBelongsToCurrentProcess := listenerPool.References(listenerKey(network, addr))\n\n\tif socketBelongsToCurrentProcess {\n\t\t// Reuse/cleanup is entirely handled by the refcounting mechanism in `listenerPool`.\n\t\treturn nil, nil\n\t}\n\n\t// If the socket file does not exist or has no backing server process, this will fail instantly.\n\tconnection, err := net.DialTimeout(\"unix\", addr, 10*time.Millisecond)\n\n\tif err == nil {\n\t\tconnection.Close()\n\t\treturn nil, fmt.Errorf(\"cannot reuse socket %v: %w\", addr, errUnixSocketAlreadyInUse)\n\t}\n\n\t// Windows returns this error code both if the socket file does not exist and if it isn't backed by a server process anymore.\n\t// See: https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2#wsaeconnrefused\n\tconst WSAECONNREFUSED syscall.Errno = 10061\n\n\tvar errno syscall.Errno\n\thasNoListeningServerProcess := errors.As(err, &errno) && errno == WSAECONNREFUSED\n\n\tif !hasNoListeningServerProcess {\n\t\treturn nil, fmt.Errorf(\"cannot reuse socket %v: %w\", addr, errUnixSocketAlreadyInUse)\n\t}\n\n\t// If the socket file exists, it hasn't been created by our process, and it seemingly\n\t// isn't backed by a server process anymore. Try to delete it so we can bind to it later.\n\terr = os.Remove(addr)\n\n\tif err == nil {","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/listen_reuseUnixSocket_windows.go#L44-L80","documentation":"During ECH key rotation, a config older than rotationInterval (30 days) with no Replaced timestamp needed a replacement, and generateAndStoreECHConfig failed — it could not generate an ECH keypair/config for the public name or persist it to storage.","triggerScenarios":"generateAndStoreECHConfig: HPKE key generation failure (extremely rare), finding a free config ID via storage trial paths failing, or storage.Store of key.bin/config.bin/meta.json under ech/configs/<id> failing (read-only, full disk, backend outage).","commonSituations":"Data volume full or read-only after 30 days of uptime when rotation first triggers; storage credentials expiring; a cluster peer holding conflicting config IDs due to divergent storage views.","solutions":["Check the wrapped error from generateAndStoreECHConfig for the exact failing step.","Ensure writable storage and adequate disk space on all instances.","Fix backend connectivity; rotation retries on the next maintenance tick.","If config ID collisions are indicated in a cluster, ensure all instances share one storage backend so ID allocation is serialized by the ech_rotation lock."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"Retry on next rotation tick after fixing storage; if generation itself fails (rare), capture the inner error and report upstream.","preventionTips":["Keep data volumes writable and non-full for the 30-day rotation window.","Use one shared storage per cluster to prevent config ID allocation races.","Monitor for rotation failures so old keys do not linger past intended lifetimes."],"tags":["caddy","caddytls","ech","rotation","storage"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}