{"record":{"id":"b6abff212e87145a","repo":"apache/seatunnel","slug":"get-sign-failed","errorCode":"GET_SIGN_FAILED","errorMessage":"Get signature from DinkTalk server failed","messagePattern":"Get signature from DinkTalk server failed","errorType":"error_code","errorClass":"DingTalkConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-dingtalk/src/main/java/org/apache/seatunnel/connectors/seatunnel/sink/DingTalkWriter.java","lineNumber":102,"sourceCode":"                        e);\n            }\n        }\n\n        public String getUrl() throws IOException {\n            Long timestamp = System.currentTimeMillis();\n            String sign = getSign(timestamp);\n            return url + \"&timestamp=\" + timestamp + \"&sign=\" + sign;\n        }\n\n        public String getSign(Long timestamp) throws IOException {\n            try {\n                String stringToSign = timestamp + \"\\n\" + secret;\n                Mac mac = Mac.getInstance(\"HmacSHA256\");\n                mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), \"HmacSHA256\"));\n                byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));\n                return URLEncoder.encode(Base64.getEncoder().encodeToString(signData), \"UTF-8\");\n            } catch (Exception e) {\n                throw new DingTalkConnectorException(\n                        DingTalkConnectorErrorCode.GET_SIGN_FAILED,\n                        \"Get signature from DinkTalk server failed\",\n                        e);\n            }\n        }\n    }\n}\n","sourceCodeStart":84,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-dingtalk/src/main/java/org/apache/seatunnel/connectors/seatunnel/sink/DingTalkWriter.java#L84-L110","documentation":"When secret-key signing mode is enabled, getSign computes an HmacSHA256 signature over '<timestamp>\\n<secret>' and URL-encodes the base64 result. Any exception (NoSuchAlgorithmException, InvalidKeyException, charset problems) is wrapped as DingTalkConnectorException(GET_SIGN_FAILED, 'Get signature from DinkTalk server failed').","triggerScenarios":"Calling getSign (via sign) when Mac.getInstance(\"HmacSHA256\") or mac.init fails, or the secret is null/empty causing SecretKeySpec construction to throw — any failure while computing the signature for the secured robot webhook.","commonSituations":"Blank or malformed secret in the sink config (SecretKeySpec rejects empty keys); JVM lacking HmacSHA256 (restricted crypto policies); trailing whitespace/newlines in copy-pasted secrets.","solutions":["Check the secret value: non-empty, correct SEC... key copied from the DingTalk robot 'sign' security setting","Verify the JVM supports HmacSHA256 (default JCE policy); use a standard JDK","Confirm the secret contains no trailing whitespace or newlines from copy-paste"],"exampleFix":"// before\nsecret = \"\" // empty -> InvalidKeyException\n// after\nsecret = \"SECxxxxxxxxxxxxxxxxxxxxxxxx\"","handlingStrategy":"validation","validationCode":"if (secret == null || secret.trim().isEmpty()) { throw new IllegalStateException(\"DingTalk secret must be the non-empty SEC... key from the robot sign setting\"); }","typeGuard":null,"tryCatchPattern":"try { writer.write(row); } catch (DingTalkConnectorException e) { if (\"GET_SIGN_FAILED\".equals(e.getErrorCode())) log.error(\"Signature computation failed - check secret/JCE\", e); throw e; }","preventionTips":["Copy the secret exactly from the DingTalk robot security config, no trailing whitespace","Use a standard JDK with default JCE policy (HmacSHA256 available)","Prefer webhook token auth over sign mode if signing keeps failing"],"tags":["dingtalk","hmac","signature"],"backgroundTag":"authentication-required","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}