Apologies, not to step on any toes but that is not going to work. It’s not that it’s in wrong it’s just incomplete. GetDefaultPawnClassForController is being called by the GameMode on the server which means it’s working with the server side version of the controller. Yes, the controller is replicated but that does not imply that all replicated variable values replicate from client to server. That would go against the server authoritative model…replication happens down, not up. If you want to effect values on the server version of anything then you must explicitely do so using server side RPCs.
Now, the issue you’re running into is that you want the connecting client to already have decided which pawn to choose BEFORE connecting. When a client attempts a connection to a server a chain of events fires off which creates the player controller, player state and pawn and hands that over to the connecting client. By time the client has a window to take action, the pawn has already been created. So what do you do? In keeping with the GetDefaulPawnClassForController theme, one solution is that you need to send the server version of the player controller what the client wants they’re pawn to be. Here’s an example implementation (albeit in C++) of exactly what you’re trying to accomplish.
Spawn Different Pawns For Players in Multiplayer - UE4: Guidebook (gg-labs.com)
Don’t let the C++ scare you if you’re not familiar…generally speaking it flows just like the BP stuff. In here the author is using GetDefaultPawnClassForController. The crucial piece that you’re missing is the push of the desired pawn to the server.
I don’t have the cycles right this second to walk you through creating that in BP, although it’s fairly straightforward. If you haven’t made any headway on it by time I’m free tonight then I can put an example together.