Simo suggests an option 6, applying only to collection types:

6. Create a new ccache within the collection to hold the new creds, and remove the old one once the new one is populated.  If the old one was the primary, set the primary to the new one before removing the old one.

Caveats of this approach:

A. krb5_cc_cache_match() needs to prefer the old one until the new one is populated.  If collection iteration respects creation order, this is automatic, but (as far as I know) no collection type currently provides that guarantee.  Otherwise krb5_cc_cache_match() needs a way to detect whether a cache is populated.

B. We need a way to remove the old one.  A krb5_cc_cache_match() before initialize the new cache could work, more or less.  (There's a danger that the old cache is destroyed by another process doing the same refresh, and then the cache name is reused for another purpose, and then we wind up destroying unrelated creds.  Unlikely if cache names are sufficiently random.)

C. Resetting the primary to reflect the update could race with another process setting the primary (either to refresh the same cache, or for another purpose entirely).

D. Nico has suggested that cache names within a collection should use the principal name rather than a random name.  That itself requires some changes to the API, but is also incompatible with this approach unless the unpopulated cache can temporarily use a different name and then be renamed.