{"record":{"id":"8de4d24b8b55c1cf","repo":"XTLS/Xray-core","slug":"new-crypto-reader-w","errorCode":null,"errorMessage":"new crypto reader: %w","messagePattern":"new crypto reader: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"transport/internet/finalmask/xmc/client.go","lineNumber":186,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"encrypt verify token: %w\", err)\n\t}\n\n\t// Send Encryption Response\n\terr = writePacket(\n\t\tc.writer,\n\t\t0x01,\n\t\t(*Bytes)(&encryptedSharedSecret),\n\t\t(*Bytes)(&encryptedVerifyToken),\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write encryption response: %w\", err)\n\t}\n\n\t// Enable encryption\n\tc.reader, err = newCryptoReader(c.reader, sharedSecret)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"new crypto reader: %w\", err)\n\t}\n\n\tc.writer, err = newCryptoWriter(c.writer, sharedSecret)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"new crypto writer: %w\", err)\n\t}\n\n\tpkt, err = readPacket(c.reader)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read login finished: %w\", err)\n\t}\n\tif pkt.packetID == 0x00 {\n\t\tvar reason String\n\t\tif readErr := pkt.readFields(&reason); readErr != nil {\n\t\t\treturn fmt.Errorf(\"authentication rejected\")\n\t\t}\n\t\treturn fmt.Errorf(\"authentication rejected: %s\", reason)\n\t}","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/xmc/client.go#L168-L204","documentation":"Constructing the AES-CFB crypto reader over the shared secret failed (newCryptoReader wraps the handshake reader with symmetric encryption). In this codebase the constructor derives an AES cipher from the 16-byte sharedSecret, so it only fails if the key length is not a valid AES size — which cannot happen since sharedSecret is hardcoded to 16 bytes. In practice this error is a defensive guard that is not expected to fire.","triggerScenarios":"Only reachable if newCryptoReader's internal aes.NewCipher(sharedSecret) fails, which requires a key size outside {16,24,32}; the fixed 16-byte allocation makes this unreachable under current code.","commonSituations":"None in normal operation. Seeing it usually means a fork modified the shared-secret size or the crypto constructor signature.","solutions":["If you maintain a fork: keep the shared secret at 16 bytes (AES-128) to match the server","Report upstream if it fires on unmodified code, since it indicates memory/state corruption","Diff local changes against upstream to find altered key-derivation logic"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := conn.Read(buf); err != nil && strings.Contains(err.Error(), \"new crypto reader\") {\n    // defensive branch: indicates modified build or corruption; do not retry\n    log.Error(\"unexpected crypto init failure\", \"err\", err)\n    return err\n}","preventionTips":["Do not change the 16-byte shared secret size in forks","Pin to upstream releases for the crypto path","Report occurrences upstream with a reproducer"],"tags":["crypto","aes","internal","go"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}