{"record":{"id":"3ad6093d2cbe1b20","repo":"coollabsio/coolify","slug":"custom-log-drain-is-not-enabled","errorCode":null,"errorMessage":"Custom log drain is not enabled.","messagePattern":"Custom log drain is not enabled\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"app/Actions/Server/StartLogDrain.php","lineNumber":132,"sourceCode":"    Rename              COOLIFY_SERVER_IP coolify.server_ip\n    Rename              COOLIFY_ENVIRONMENT_NAME coolify.environment_name\n[OUTPUT]\n    Name            http\n    Match           *\n    Host            api.axiom.co\n    Port            443\n    URI             /v1/datasets/\\${AXIOM_DATASET_NAME}/ingest\n    # Authorization Bearer should be an API token\n    Header Authorization Bearer \\${AXIOM_API_KEY}\n    compress gzip\n    format json\n    json_date_key _time\n    json_date_format iso8601\n    tls On\n\");\n            } elseif ($type === 'custom') {\n                if (! $server->settings->is_logdrain_custom_enabled) {\n                    throw new \\Exception('Custom log drain is not enabled.');\n                }\n                $config = base64_encode($server->settings->logdrain_custom_config);\n                $parsers = base64_encode($server->settings->logdrain_custom_config_parser);\n            } else {\n                throw new \\Exception('Unknown log drain type.');\n            }\n            if ($type !== 'custom') {\n                $parsers = base64_encode(\"\n[PARSER]\n    Name        empty_line_skipper\n    Format      regex\n    Regex       /^(?!\\s*$).+/\n\");\n            }\n            $compose = base64_encode('\nservices:\n  coolify-log-drain:\n    image: cr.fluentbit.io/fluent/fluent-bit:2.0","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Actions/Server/StartLogDrain.php#L114-L150","documentation":"Fourth defensive guard: $type === 'custom' was selected because is_logdrain_custom_enabled was true, so the re-check at the top of the branch cannot fail under normal flow. Reachable only via a concurrent settings mutation/refresh race. On success this branch base64-encodes logdrain_custom_config and logdrain_custom_config_parser from settings — so a race can also mean those fields were emptied mid-flight.","triggerScenarios":"Concurrent save that disables the custom log drain (or empties logdrain_custom_config) while the queued StartLogDrain job executes against a refreshed settings relation.","commonSituations":"Editing the custom Fluent Bit config in the UI while a drain restart is queued; scripts toggling drain settings in parallel.","solutions":["Re-run StartLogDrain once the custom config and enable flag are stable.","Save the custom config and the enable flag together, in one request.","Validate logdrain_custom_config is non-empty before enabling the custom drain."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (! $server->settings->is_logdrain_custom_enabled) {\n    return 'Enable the custom log drain before starting it.';\n}\nif (blank($server->settings->logdrain_custom_config)) {\n    return 'Custom log drain needs a Fluent Bit config before it can start.';\n}\nStartLogDrain::run($server);","typeGuard":"function activeLogDrainType(\\App\\Models\\Server $server): string\n{\n    $s = $server->settings;\n    if ($s->is_logdrain_newrelic_enabled) { return 'newrelic'; }\n    if ($s->is_logdrain_highlight_enabled) { return 'highlight'; }\n    if ($s->is_logdrain_axiom_enabled) { return 'axiom'; }\n    if ($s->is_logdrain_custom_enabled) { return 'custom'; }\n    return 'none';\n}","tryCatchPattern":"try {\n    StartLogDrain::run($server);\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'log drain is not enabled')) {\n        StartLogDrain::run($server->refresh()); // retry once after settings settle\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Validate the custom Fluent Bit config is non-empty before enabling the flag.","Save logdrain_custom_config, logdrain_custom_config_parser and the enable flag in one atomic update.","Test custom configs with a local Fluent Bit before pushing them to production servers."],"tags":["log-drain","custom-config","fluent-bit","race-condition","settings"],"backgroundTag":"log-drain-not-configured","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}