{"record":{"id":"4e045b09e23bac51","repo":"louislam/uptime-kuma","slug":"additional-headers-is-not-a-valid-json","errorCode":null,"errorMessage":"Additional Headers is not a valid JSON","messagePattern":"Additional Headers is not a valid JSON","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/notification-providers/smtp.js","lineNumber":66,"sourceCode":"        }\n\n        // Should fix the issue in https://github.com/louislam/uptime-kuma/issues/26#issuecomment-896373904\n        if (notification.smtpUsername || notification.smtpPassword) {\n            config.auth = {\n                user: notification.smtpUsername,\n                pass: notification.smtpPassword,\n            };\n        }\n\n        // Handle additional headers\n        if (notification.smtpAdditionalHeaders) {\n            try {\n                config.headers = {\n                    ...config.headers,\n                    ...JSON.parse(notification.smtpAdditionalHeaders),\n                };\n            } catch (err) {\n                throw new Error(\"Additional Headers is not a valid JSON\");\n            }\n        }\n\n        // default values in case the user does not want to template\n        let subject = msg;\n        let body = msg;\n        let useHTMLBody = false;\n        if (heartbeatJSON) {\n            body = `${msg}\\nTime (${heartbeatJSON[\"timezone\"]}): ${heartbeatJSON[\"localDateTime\"]}`;\n        }\n        // subject and body are templated\n        if ((monitorJSON && heartbeatJSON) || msg.endsWith(\"Testing\")) {\n            // cannot end with whitespace as this often raises spam scores\n            const customSubject = notification.customSubject?.trim() || \"\";\n            const customBody = notification.customBody?.trim() || \"\";\n            if (customSubject !== \"\") {\n                subject = await this.renderTemplate(customSubject, msg, monitorJSON, heartbeatJSON);\n            }","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/notification-providers/smtp.js#L48-L84","documentation":"Thrown by the SMTP provider when JSON.parse fails on the user-supplied notification.smtpAdditionalHeaders string. The field is expected to hold a JSON object of extra MIME/SMTP headers (e.g. {\"X-Custom\":\"value\"}); any malformed JSON raises SyntaxError which is caught and re-thrown with this message before nodemailer is constructed.","triggerScenarios":"Entering key: value pairs without braces/quotes, trailing commas, single-quoted keys, pasting from a YAML/curl -H list, or HTML entity encoding from a rich-text editor.","commonSituations":"User copies headers from a curl -H invocation, uses Python-dict syntax instead of JSON, or the UI field is filled with newlines that break strict JSON parsing.","solutions":["Validate the value in a JSON linter (jsonlint.com) before saving.","Use double quotes for both keys and string values and wrap the whole thing in {}.","Remove trailing commas and comments — strict JSON allows neither.","If you need multiple headers, express them as one object: {\"X-A\":\"1\",\"X-B\":\"2\"}."],"exampleFix":"// before (in notification config)\nsmtpAdditionalHeaders: X-Priority: 1, X-MSMail-Priority: High\n// after\nsmtpAdditionalHeaders: {\"X-Priority\":\"1\",\"X-MSMail-Priority\":\"High\"}","handlingStrategy":"validation","validationCode":"// Validate additional headers BEFORE building the transporter\nfunction parseAdditionalHeaders(raw) {\n    if (!raw) return {};\n    let parsed;\n    try {\n        parsed = JSON.parse(raw);\n    } catch (e) {\n        throw new Error(`Additional Headers is not valid JSON: ${e.message}`);\n    }\n    if (typeof parsed !== \"object\" || Array.isArray(parsed) || parsed === null) {\n        throw new Error(\"Additional Headers must be a JSON object\");\n    }\n    return parsed;\n}\nconfig.headers = { ...config.headers, ...parseAdditionalHeaders(notification.smtpAdditionalHeaders) };","typeGuard":"/** True when raw parses to a flat object of header strings. */\nfunction isValidHeadersObject(raw) {\n    try {\n        const o = JSON.parse(raw);\n        return o && typeof o === \"object\" && !Array.isArray(o) &&\n            Object.values(o).every((v) => typeof v === \"string\");\n    } catch { return false; }\n}","tryCatchPattern":"try {\n    config.headers = { ...config.headers, ...JSON.parse(notification.smtpAdditionalHeaders) };\n} catch (err) {\n    throw new Error(`Additional Headers is not a valid JSON: ${err.message}`);\n}","preventionTips":["Run header JSON through jsonlint.com before saving.","Use double-quoted keys and values, no trailing commas.","Add a client-side JSON validator in the notification form."],"tags":["smtp","notification-provider","config","json","validation"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}