Turning the daemon's logging on (1f339a8) made this visible immediately, on every sync cycle:
WARN nobilis::backend::matrix::crypto: matrix crypto: outgoing request failed
(will retry next cycle): keys/upload: M_INVALID_PARAM: 1 validation error
for KeyUploadRequestBody
Value error, device_keys must not be null
keys/upload is how a device publishes its identity and one-time keys. It is failing against poast.org because the request is being sent with device_keys: null rather than omitting the field — the homeserver validates it as present-and-null and refuses. It then retries forever, so the log fills at sync cadence.
The consequence is not cosmetic. If device keys never upload, other people's clients cannot establish Olm sessions with this device, which means messages encrypted to it may be undecryptable and this device is not properly announced to the room. It may also be part of why anything shows [unable to decrypt message].
Where to look: backend/matrix/crypto.rs:175-275 assembles the /keys/upload body by hand from OutgoingRequest. The fix is almost certainly to omit device_keys when the machine did not produce one — serialising Option::None as null where the endpoint expects the key to be absent.
Found while working the IRC issues, so not investigated further than the log line.
Turning the daemon's logging on (1f339a8) made this visible immediately, on every sync cycle:
```
WARN nobilis::backend::matrix::crypto: matrix crypto: outgoing request failed
(will retry next cycle): keys/upload: M_INVALID_PARAM: 1 validation error
for KeyUploadRequestBody
Value error, device_keys must not be null
```
`keys/upload` is how a device publishes its identity and one-time keys. It is failing against poast.org because the request is being sent with `device_keys: null` rather than omitting the field — the homeserver validates it as present-and-null and refuses. It then retries forever, so the log fills at sync cadence.
The consequence is not cosmetic. If device keys never upload, other people's clients cannot establish Olm sessions with this device, which means messages encrypted *to* it may be undecryptable and this device is not properly announced to the room. It may also be part of why anything shows `[unable to decrypt message]`.
Where to look: `backend/matrix/crypto.rs:175-275` assembles the `/keys/upload` body by hand from `OutgoingRequest`. The fix is almost certainly to omit `device_keys` when the machine did not produce one — serialising `Option::None` as `null` where the endpoint expects the key to be absent.
Found while working the IRC issues, so not investigated further than the log line.
The body was built as one json! literal, and a literal turns an absent value into an explicit null. The specification says these fields are absent when there is nothing to send, which is a different thing entirely.
Synapse accepts "device_keys": null and ignores it, which is why this looked fine for as long as nobody pointed moho at a stricter homeserver. poast.org validates the body and refuses the whole request, on every sync cycle, forever — the retry sends the same thing again.
Empty one_time_keys and fallback_keys maps are omitted for the same reason: "here are no keys" and "I am not uploading keys" are different requests.
Verified against your account: zero keys/upload failures since the restart, where previously they appeared within seconds of connecting and repeated at sync cadence. Matrix is connected, syncing, and listing both devices.
Worth recording how this was found: only because the daemon's logging was switched on while chasing the Sneedchat whisper bug. It had been failing silently the entire time — which is the same lesson as #73 and the whisper key, and the reason 1f339a8 was worth doing.
Finished — https://git.salastil.com/Salastil/nobilis/commit/1f0d947
The body was built as one `json!` literal, and a literal turns an absent value into an explicit `null`. The specification says these fields are **absent** when there is nothing to send, which is a different thing entirely.
Synapse accepts `"device_keys": null` and ignores it, which is why this looked fine for as long as nobody pointed moho at a stricter homeserver. poast.org validates the body and refuses the whole request, on every sync cycle, forever — the retry sends the same thing again.
Empty `one_time_keys` and `fallback_keys` maps are omitted for the same reason: "here are no keys" and "I am not uploading keys" are different requests.
Verified against your account: zero `keys/upload` failures since the restart, where previously they appeared within seconds of connecting and repeated at sync cadence. Matrix is connected, syncing, and listing both devices.
Worth recording how this was found: only because the daemon's logging was switched on while chasing the Sneedchat whisper bug. It had been failing silently the entire time — which is the same lesson as #73 and the whisper key, and the reason 1f339a8 was worth doing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Turning the daemon's logging on (1f339a8) made this visible immediately, on every sync cycle:
keys/uploadis how a device publishes its identity and one-time keys. It is failing against poast.org because the request is being sent withdevice_keys: nullrather than omitting the field — the homeserver validates it as present-and-null and refuses. It then retries forever, so the log fills at sync cadence.The consequence is not cosmetic. If device keys never upload, other people's clients cannot establish Olm sessions with this device, which means messages encrypted to it may be undecryptable and this device is not properly announced to the room. It may also be part of why anything shows
[unable to decrypt message].Where to look:
backend/matrix/crypto.rs:175-275assembles the/keys/uploadbody by hand fromOutgoingRequest. The fix is almost certainly to omitdevice_keyswhen the machine did not produce one — serialisingOption::Noneasnullwhere the endpoint expects the key to be absent.Found while working the IRC issues, so not investigated further than the log line.
Finished — https://git.salastil.com/Salastil/nobilis/commit/1f0d947
The body was built as one
json!literal, and a literal turns an absent value into an explicitnull. The specification says these fields are absent when there is nothing to send, which is a different thing entirely.Synapse accepts
"device_keys": nulland ignores it, which is why this looked fine for as long as nobody pointed moho at a stricter homeserver. poast.org validates the body and refuses the whole request, on every sync cycle, forever — the retry sends the same thing again.Empty
one_time_keysandfallback_keysmaps are omitted for the same reason: "here are no keys" and "I am not uploading keys" are different requests.Verified against your account: zero
keys/uploadfailures since the restart, where previously they appeared within seconds of connecting and repeated at sync cadence. Matrix is connected, syncing, and listing both devices.Worth recording how this was found: only because the daemon's logging was switched on while chasing the Sneedchat whisper bug. It had been failing silently the entire time — which is the same lesson as #73 and the whisper key, and the reason 1f339a8 was worth doing.