I ended up finding an issue in node-red-contrib-coap where the content format is being set to one of three options and none of them allow just an unchanged payload to pass through.
My quick and dirty fix was to set text/plain to msg.payload
if (_checkContentFormat(contentFormat, "text/plain")) {
return msg.payload.toString();
} else if (_checkContentFormat(contentFormat, "json")) {
return JSON.stringify(msg.payload);
} else if (_checkContentFormat(contentFormat, "cbor")) {
return cbor.encode(msg.payload);
} else {
return msg.payload.toString();
}