The behavior is covered in [dcl.fct.def.default]p3 which says:
If a function that is explicitly defaulted is declared with a noexcept-specifier that does not produce the same
exception specification as the implicit declaration (18.4), then
(3.1) — if the function is explicitly defaulted on its first declaration, it is defined as deleted;
(3.2) — otherwise, the program is ill-formed.
Note the wording changes in C++20 but the intent is the same for this case. I find the C++17 wording simpler to grok.
For example given:
struct S {
S( S&& ) noexcept(false) = default;
};
The move constructor is defined as deleted since due to [except.spec]p7:
An implicitly-declared constructor for a class X, or a constructor without a noexcept-specifier that is defaulted
on its first declaration, has a potentially-throwing exception specification if and only if any of the following
constructs is potentially-throwing:
(7.1) — a constructor selected by overload resolution in the implicit definition of the constructor for class X to
initialize a potentially constructed subobject, or
(7.2) — a subexpression of such an initialization, such as a default argument expression, or,
(7.3) — for a default constructor, a default member initializer.
none of the cases hold.
If we got back to [dcl.fct.def.default]p3 it says otherwise the program is ill-formed. Ill-formed programs require a diagnostic so if we modify the first example as follows (see it live):
struct S {
S( S&& ) noexcept(false) ;
private:
int i;
};
S::S( S&&) noexcept(false) = default ;
it will produce a diagnostic e.g.:
error: function 'S::S(S&&)' defaulted on its redeclaration with an exception-specification that differs from the implicit exception-specification 'noexcept'
S::S( S&&) noexcept(false) = default ;
^
Note clang bug related to this case, it seems they are not following Defect Report 1778.
You may want to note Declaring a function as defaulted after its first declaration which covers some the optimization/interface issues.