Both flags will cause undeliverable messages to be returned in certain cases. The returned messages arrive like delivered messages (asynchronously) on the session->returned_basic_list, just as delivered messages arrive on the session->delivered_basic_list.
The mandatory flag means, "return the message if it cannot be routed by the exchange", and the immediate flag means, "return the message if it cannot be delivered by the queue right away".
In a typical service-oriented model, each service is a queue bound to an exchange like amq.direct. The mandatory flag says, "return the message if no service is active" and the immediate flag says, "return the message if the service is busy".
We return the whole message, rather than just headers, so that the application can process it without any other context.