Let's start with some background: per the documentation, you need to call va_start before invoking va_arg on any va_list:
"va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg". (Source)
"Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end". (Source)
I would imagine not calling va_start is undefined behavior, but I couldn't find a specific callout to state as such.
In your question, the function int max(int n, va_list vals) is not "really" variadic, since it accepts a fixed number of arguments: 2. These are int n and va_list vals.
Per the documentation "The declaration of a variadic function uses an ellipsis as the last parameter, e.g. int printf(const char* format, ...);"
So, it depends on how you implement it, but I would recommend documenting the int max(int n, va_list vals) to accept a va_list that is already initialized with a va_start call. The rationale being that it is not technically "variadic" and does not really "own" the va_list. It just accepts it as an input from some other source.
The actual variadic function int max_first(int n, ...) should be the one creating the va_list and priming it with the call to va_start before passing it anywhere.
Although, as far as I can tell, there's no way to check if a va_list already has va_start called on it or not. And there's no guarantee that it will be called before being passed to your function, so I suspect this would have to be enforced by documentation and convention.