From RFC 7234:
The “max-age” request directive indicates that the client is
unwilling to accept a response whose age is greater than the
specified number of seconds. Unless the max-stale request directive
is also present, the client is not willing to accept a stale
response.
…
The “max-stale” request directive indicates that the client is
willing to accept a response that has exceeded its freshness
lifetime. If max-stale is assigned a value, then the client is
willing to accept a response that has exceeded its freshness lifetime
by no more than the specified number of seconds.
That is, max-age
is the oldest that a response can be, as long as the Cache-Control
from the origin server indicates that it is still fresh. max-stale
indicates that, even if the response is known to be stale, you will also accept it as long as it’s only stale by that number of seconds.
As per Serving Stale Responses:
A cache SHOULD generate a Warning header field with the 110 warn-code
(see Section 5.5.1) in stale responses.
So, if you specified max-stale
and received a no-longer-fresh response, the Warning
header would let you know.