diff --git a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/AbstractUserUpdater.java b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/AbstractUserUpdater.java
index 0afb7410654da1da1997a3fb37a7bbd81aafbc7d..0fdea223f87858d776f9b7da346c779733c79e37 100644
--- a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/AbstractUserUpdater.java
+++ b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/AbstractUserUpdater.java
@@ -109,14 +109,58 @@ public abstract class AbstractUserUpdater<T extends UserEntity> implements UserU
 	public abstract boolean updateUserFromAttribute(T user, Map<String, List<Object>> attributeMap,
 			boolean withoutUidNumber, Auditor auditor) throws UserUpdateException;
 
-	public abstract Map<String, String> resolveHomeOrgGenericStore(T user); 
-	public abstract IncomingAttributesHandler<?> resolveIncomingAttributeHandler(T user); 
-	
+	public abstract Map<String, String> resolveHomeOrgGenericStore(T user);
+
+	public abstract IncomingAttributesHandler<?> resolveIncomingAttributeHandler(T user);
+
 	public boolean updateUserFromAttribute(T user, Map<String, List<Object>> attributeMap, Auditor auditor)
 			throws UserUpdateException {
 		return updateUserFromAttribute(user, attributeMap, false, auditor);
 	}
 
+	@Override
+	public T expireUser(T user, String executor) {
+		logger.info("Expiring user {}. Trying one last update", user.getId());
+
+		UserUpdateAuditor auditor = new UserUpdateAuditor(auditDao, auditDetailDao, appConfig);
+		auditor.startAuditTrail(executor);
+		auditor.setName(getClass().getName() + "-UserExpire-Audit");
+		auditor.setDetail("Expire user " + user.getId());
+
+		try {
+			user = updateUserFromHomeOrg(user, null, executor, null);
+
+			// User update from home org did not fail. That means, we don't need to bother
+			// the user to login. Clear the expiry warning, things should be done
+			// automatically
+			user.setExpireWarningSent(null);
+
+			return user;
+
+		} catch (UserUpdateException e) {
+			// The Exception is expected, because the home org will not accept user updates
+			// in the back channel. The user already got an expire warning at this point.
+			user.getAttributeStore().clear();
+
+			// user empty attribute map in order to remove all existing values
+			IncomingAttributeSetEntity incomingAttributeSet = resolveIncomingAttributeHandler(user)
+					.createOrUpdateAttributes(user, new HashMap<>());
+			resolveIncomingAttributeHandler(user).processIncomingAttributeSet(incomingAttributeSet);
+
+			// sets user account on ON_HOLD, if it's in state ACTIVE
+			deactivateUser(user, auditor);
+
+			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+			user.getGenericStore().put("epired_on", df.format(new Date()));
+
+			return user;
+		} finally {
+			auditor.setUser(user);
+			auditor.finishAuditTrail();
+			auditor.commitAuditTrail();
+		}
+	}
+
 	public T updateUser(T user, Map<String, List<Object>> attributeMap, String executor, StringBuffer debugLog,
 			String lastLoginHost) throws UserUpdateException {
 		return updateUser(user, attributeMap, executor, null, debugLog, lastLoginHost);
@@ -132,7 +176,7 @@ public abstract class AbstractUserUpdater<T extends UserEntity> implements UserU
 		UserUpdateAuditor auditor = new UserUpdateAuditor(auditDao, auditDetailDao, appConfig);
 		auditor.startAuditTrail(executor);
 		auditor.setName(getClass().getName() + "-UserUpdate-Audit");
-		auditor.setDetail("Update user " + user.getEppn());
+		auditor.setDetail("Update user " + user.getId());
 
 		changed |= preUpdateUser(user, attributeMap, resolveHomeOrgGenericStore(user), executor, service, debugLog);
 
@@ -157,12 +201,13 @@ public abstract class AbstractUserUpdater<T extends UserEntity> implements UserU
 			user.getAttributeStore().clear();
 
 			// user empty attribute map in order to remove all existing values
-			IncomingAttributeSetEntity incomingAttributeSet = resolveIncomingAttributeHandler(user).createOrUpdateAttributes(user, new HashMap<>());
+			IncomingAttributeSetEntity incomingAttributeSet = resolveIncomingAttributeHandler(user)
+					.createOrUpdateAttributes(user, new HashMap<>());
 			resolveIncomingAttributeHandler(user).processIncomingAttributeSet(incomingAttributeSet);
 
 			// sets user account on ON_HOLD, if it's in state ACTIVE
 			deactivateUser(user, auditor);
-			
+
 		} else {
 			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
 			user.getGenericStore().put("no_assertion_count", "0");
@@ -184,9 +229,10 @@ public abstract class AbstractUserUpdater<T extends UserEntity> implements UserU
 				attributeStore.put(entry.getKey(), attrHelper.attributeListToString(entry.getValue()));
 			}
 
-			IncomingAttributeSetEntity incomingAttributeSet = resolveIncomingAttributeHandler(user).createOrUpdateAttributes(user, attributeMap);
+			IncomingAttributeSetEntity incomingAttributeSet = resolveIncomingAttributeHandler(user)
+					.createOrUpdateAttributes(user, attributeMap);
 			resolveIncomingAttributeHandler(user).processIncomingAttributeSet(incomingAttributeSet);
-			
+
 			identityUpdater.updateIdentity(user);
 
 			if (appConfig.getConfigValue("create_missing_eppn_scope") != null) {
@@ -240,6 +286,7 @@ public abstract class AbstractUserUpdater<T extends UserEntity> implements UserU
 
 		return user;
 	}
+
 	public abstract HomeOrgGroupUpdater<T> getGroupUpdater();
 
 	protected boolean preUpdateUser(T user, Map<String, List<Object>> attributeMap,
diff --git a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/OAuthUserUpdater.java b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/OAuthUserUpdater.java
index 6c816bcd77e8dc49eac51ddcdc60ec544f445f8a..8c4b7dcbd020afc5a52d7f209f722896288025db 100644
--- a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/OAuthUserUpdater.java
+++ b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/OAuthUserUpdater.java
@@ -55,6 +55,7 @@ public class OAuthUserUpdater extends AbstractUserUpdater<OAuthUserEntity> {
 
 	public OAuthUserEntity updateUserFromHomeOrg(OAuthUserEntity user, ServiceEntity service, String executor,
 			StringBuffer debugLog) throws UserUpdateException {
+		updateFail(user);
 		throw new UserUpdateException("Not implemented");
 	}
 	
@@ -174,12 +175,6 @@ public class OAuthUserUpdater extends AbstractUserUpdater<OAuthUserEntity> {
 		user.setScheduledUpdate(getNextScheduledUpdate());
 	}
 
-	@Override
-	public OAuthUserEntity expireUser(OAuthUserEntity user) throws UserUpdateException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
 	@Override
 	public HomeOrgGroupUpdater<OAuthUserEntity> getGroupUpdater() {
 		return oauthGroupUpdater;
diff --git a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/OidcUserUpdater.java b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/OidcUserUpdater.java
index 9103738f25c3c8f3319fbad3343d92778cf8305c..07bf647ca523c2ebfbfaf032a25d4bf6243e79df 100644
--- a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/OidcUserUpdater.java
+++ b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/OidcUserUpdater.java
@@ -121,6 +121,7 @@ public class OidcUserUpdater extends AbstractUserUpdater<OidcUserEntity> {
 				logger.info("Got error: code {}, desc {}, http-status {}, uri {}", error.getCode(),
 						error.getDescription());
 				updateFail(user);
+				throw new UserUpdateException();
 			} else {
 				OIDCTokenResponse oidcTokenResponse = (OIDCTokenResponse) tokenResponse.toSuccessResponse();
 				logger.debug("response: {}", oidcTokenResponse.toJSONObject());
@@ -166,6 +167,7 @@ public class OidcUserUpdater extends AbstractUserUpdater<OidcUserEntity> {
 				UserInfoResponse userInfoResponse = UserInfoResponse.parse(httpResponse);
 
 				if (!userInfoResponse.indicatesSuccess()) {
+					updateFail(user);
 					throw new UserUpdateException("got userinfo error response: "
 							+ userInfoResponse.toErrorResponse().getErrorObject().getDescription());
 				}
@@ -325,12 +327,6 @@ public class OidcUserUpdater extends AbstractUserUpdater<OidcUserEntity> {
 		user.setScheduledUpdate(getNextScheduledUpdate());
 	}
 
-	@Override
-	public OidcUserEntity expireUser(OidcUserEntity user) throws UserUpdateException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
 	@Override
 	public HomeOrgGroupUpdater<OidcUserEntity> getGroupUpdater() {
 		return oidcGroupUpdater;
diff --git a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/SamlUserUpdater.java b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/SamlUserUpdater.java
index 33eff071799972b393dcca50576c21013bdf5614..ec61616e8efd606681b090e6e3458c261e0aa1ba 100644
--- a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/SamlUserUpdater.java
+++ b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/SamlUserUpdater.java
@@ -408,12 +408,6 @@ public class SamlUserUpdater extends AbstractUserUpdater<SamlUserEntity> {
 		return true;
 	}
 
-	@Override
-	public SamlUserEntity expireUser(SamlUserEntity user) throws UserUpdateException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
 	@Override
 	public HomeOrgGroupUpdater<SamlUserEntity> getGroupUpdater() {
 		return homeOrgGroupUpdater;
diff --git a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/UserUpdater.java b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/UserUpdater.java
index 858a3e714713e181cfa5b8fc6ee8dd96bcb86db4..b4f6b4e1bc9f84bf9aacbcf09ea0e69ccb81be2f 100644
--- a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/UserUpdater.java
+++ b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/impl/UserUpdater.java
@@ -18,5 +18,5 @@ public interface UserUpdater<T extends UserEntity> {
 	public T updateUserFromHomeOrg(T user, ServiceEntity service, String executor,
 			StringBuffer debugLog) throws UserUpdateException;
 
-	public T expireUser(T user) throws UserUpdateException;
+	public T expireUser(T user, String executor);
 }
diff --git a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/user/UserLifecycleManager.java b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/user/UserLifecycleManager.java
index 5bbb00eb88f91e56af1a549ca19b2dc9117a3a37..0a4d4a774277e0ed1b9cd6105b8090f93c82442d 100644
--- a/regapp-idty/src/main/java/edu/kit/scc/webreg/service/user/UserLifecycleManager.java
+++ b/regapp-idty/src/main/java/edu/kit/scc/webreg/service/user/UserLifecycleManager.java
@@ -60,35 +60,41 @@ public class UserLifecycleManager implements Serializable {
 	private OAuthUserUpdater oauthUserUpdater;
 
 	public void sendUserExpiryWarning(UserEntity user, String emailTemplateName) {
-		logger.debug("Sending expiry warning to user {} to e-mail address {}", user.getId(),
+		logger.debug("Trying to send expiry warning to user {} to e-mail address {}. First updating...", user.getId(),
 				user.getIdentity().getPrimaryEmail());
-		sendMail(user, emailTemplateName);
-		user.setExpireWarningSent(new Date());
 
+		try {
+			if (user instanceof SamlUserEntity) {
+				user = userUpdater.updateUserFromHomeOrg((SamlUserEntity) user, null, "user-expire-job", null);
+			} else if (user instanceof OidcUserEntity) {
+				user = oidcUserUpdater.updateUserFromHomeOrg((OidcUserEntity) user, null, "user-expire-job", null);
+			} else if (user instanceof OAuthUserEntity) {
+				user = oauthUserUpdater.updateUserFromHomeOrg((OAuthUserEntity) user, null, "user-expire-job", null);
+			}
+			
+			logger.info("Update didn't fail. Don't send expiry warning to user");
+		} catch (UserUpdateException e) {
+			logger.debug("Update failed, sending expiry warning to user {} to e-mail address {}", user.getId(),
+					user.getIdentity().getPrimaryEmail());
+			sendMail(user, emailTemplateName);
+			user.setExpireWarningSent(new Date());
+		}
 	}
 
 	public void expireUser(UserEntity user, String emailTemplateName) {
 		logger.debug("Trying to expire user {} with e-mail address {}", user.getId(),
 				user.getIdentity().getPrimaryEmail());
 
-		try {
-			if (user instanceof SamlUserEntity) {
-				user = userUpdater.updateUserFromIdp((SamlUserEntity) user, "user-expire-job");
-				// TODO: call and implement expire function
-			}
-			else if (user instanceof OidcUserEntity) {
-				user = oidcUserUpdater.updateUserFromOP((OidcUserEntity) user, "user-expire-job", null);
-				// TODO: call and implement expire function
-			}
-			else if (user instanceof OAuthUserEntity) {
-				user = oauthUserUpdater.updateUserFromOP((OAuthUserEntity) user, "user-expire-job", null);
-				// TODO: call and implement expire function
-			}
-		} catch (UserUpdateException e) {
-
+		if (user instanceof SamlUserEntity) {
+			user = userUpdater.expireUser((SamlUserEntity) user, "user-expire-job");
+		} else if (user instanceof OidcUserEntity) {
+			user = oidcUserUpdater.expireUser((OidcUserEntity) user, "user-expire-job");
+		} else if (user instanceof OAuthUserEntity) {
+			user = oauthUserUpdater.expireUser((OAuthUserEntity) user, "user-expire-job");
 		}
-		//sendMail(user, emailTemplateName);
-		//user.setExpiredSent(new Date());
+
+		sendMail(user, emailTemplateName);
+		user.setExpiredSent(new Date());
 	}
 
 	private void sendMail(UserEntity user, String emailTemplateName) {