The first lesson to take from this is: if you use the iostat= specifier, check the result. However, the behaviour of your code is seemingly not guaranteed. I'll base this part of the answer on intepreting how your compiler is taking things.
In addition to the iostat= specifier, in general you can use, as Vladimir F mentions in a comment, the iomsg= specifier to get a friendly message. [As IanH notes, the nominated variable is updated, and in particular may otherwise remain undefined, only in situations where the variable for the iostat= specifier is (or would be) set to non-zero.]
character (len=10) s
character (len=58) mesg
integer ios
write(s,*, iostat=ios, iomsg=mesg) 7
if (ios/=0) print*, ios, TRIM(mesg)
You want to check this, because you are using list-directed output. Here, the compiler is free to choose "reasonable" values for the integer edit format. It's more than likely that, for default integer kind, the field would be longer than 9 (don't forget the leading blank). Thus, it doesn't "fit" into the length-10 character record: "End of record" would be reasonable for mesg in this case.
With the explicit format I3 it fits with much to spare.
Why you see LEN_TRIM(s) as 10, is that s actually likely becomes junk.
Now, coming to the final part. It appears that your code with list-directed output is not valid. Fortran 2008 (and I presume many others) explicitly states:
On output, the output list and format specification shall not specify more characters for a record than ... the record length of an internal file.
The record length of your internal file being 10.
The usual caveats of relying on any particular behaviour hold. I'd be disappointed, though, if something dramatic happened.
iosin the first case? What do you get forLEN_TRIM(s)in the second? [I guess it's greater than 10.]iomsgtoo and read why it fails.